2
3
mirror of https://foundry.openuru.org/gitblit/r/CWE-ou-minkata.git synced 2025-07-15 10:54:18 +00:00

Compare commits

..

56 Commits

Author SHA1 Message Date
883495c35c Merge branch 'ticket/53' 2023-10-23 15:12:43 -06:00
e1306da736 Merge branch 'ticket/52' 2023-10-23 15:12:40 -06:00
8d1d813df5 Merge branch 'ticket/51' 2023-10-23 15:12:37 -06:00
65d50895bb closes #53 2023-10-23 15:12:15 -06:00
6a41bdbee7 closes #52 2023-10-23 15:11:45 -06:00
3dcf1c2f26 closes #51 2023-10-23 15:11:03 -06:00
70449244f4 Merge branch 'ticket/53' 2023-10-02 20:13:56 -06:00
82abcb2f07 remove clearReceivers() 2023-10-02 10:34:28 -07:00
870d0534df Merge branch 'ticket/53' 2023-09-29 10:49:27 -06:00
1f09d6c48a Try without armature changes 2023-09-28 11:48:33 -07:00
66ce08ed67 Merge branch 'ticket/53' 2023-09-26 10:08:18 -06:00
1c1d3dd82e Merge branch 'ticket/52' 2023-09-26 10:08:14 -06:00
4924156ad4 Fix 3 problems with plSubWorldMsg.
Co-authored-by: Adam Johnson <AdamJohnso@gmail.com>
2023-09-18 09:50:23 -07:00
13ea0a98de Don't trust the local machine's system time.
Co-authored-by: Adam Johnson <AdamJohnso@gmail.com>
2023-09-18 09:41:33 -07:00
f9723462d7 Merge branch 'ticket/51' 2023-07-05 15:00:20 -06:00
7d3774a732 Unload all keys of all pages before deleting them
(ported from H-uru/Plasma@04d0ac94ea)
2023-06-29 22:04:17 +02:00
ea7e4b2ab5 Fix previous commits not actually nulling out the key
I goofed while porting this from H'uru, where the variable is a
reference. The previous code actually caused the keys to not get deleted
at all.
2023-06-26 00:16:24 +02:00
5d5ba00f7d Also guard against accessing plRegistryKeyList currently being deleted
Co-authored-by: Adam Johnson <AdamJohnso@gmail.com>

(ported from H-uru/Plasma@725eeaa288)
2023-06-25 16:50:10 +02:00
af38137822 Fix possible use after free in plRegistryPageNode::UnloadKeys
Short explanation: the destructor of plRegistryKeyList may indirectly
access other entries of fKeyLists where the plRegistryKeyList has
already been deleted, but not yet removed from the map.

Long explanation:
* Deleting a plRegistryKeyList also deletes all plKeys inside it, which
  decrements the reference count of the objects they point to.
* If one of the deleted keys happens to be the last reference to an
  object, this also deletes the object itself.
* The object's destructor might in turn delete another plKey, which
  calls SetKeyUnused, which tries to look up the key in its page.
* If this second plKey belongs to the page that is currently being
  unloaded, then its plRegistryKeyList may be partially or completely
  deleted, but still listed in the fKeyLists map. In this case, the key
  lookup accesses already freed memory.

(ported from H-uru/Plasma@a529e35fd9)
2023-06-25 16:44:35 +02:00
4b0ab75a79 Merge branch 'ticket/49' 2022-11-12 10:30:24 -07:00
dcb0309a08 closes #49 2022-11-12 10:29:57 -07:00
7dde0855dc Merge branch 'ticket/48' 2022-11-12 10:13:57 -07:00
44c9b0694d Merge branch 'ticket/47' 2022-11-12 10:13:53 -07:00
dedf04ac43 Merge branch 'ticket/45' 2022-11-12 10:13:50 -07:00
eeb458817f Merge branch 'ticket/44' 2022-11-12 10:13:43 -07:00
68c7187155 closes #48 2022-11-12 10:13:17 -07:00
6fa695a2c3 closes #47 2022-11-12 10:12:53 -07:00
2a3c1b32ef closes #45 2022-11-12 10:11:59 -07:00
d3cbaa94ef closes #44 2022-11-12 10:11:24 -07:00
e7758ccc10 Merge branch 'ticket/49' 2022-10-23 10:46:15 -06:00
07b92234ad Fix bug for python SDL variable-length arrays 2022-10-03 21:48:57 -05:00
7dfa2ba56a Merge branch 'master' into working 2022-07-19 08:55:00 -06:00
1a091b7019 Merge branch 'ticket/48' 2022-06-05 15:14:09 -06:00
104a5ef4ee Merge branch 'ticket/47' 2022-06-05 15:13:55 -06:00
19cfaaaea9 Merge branch 'ticket/45' 2022-06-05 15:13:41 -06:00
dafd190083 Merge branch 'ticket/44' 2022-06-05 15:13:26 -06:00
fdee5a921b Merge branch 'ticket/47' of https://foundry.openuru.org/gitblit/r/CWE-ou-minkata into ticket/47 2022-05-30 14:23:43 -07:00
b322ee094c Fix compile error 2022-05-30 14:23:20 -07:00
54c768d966 PR from Huru to prevent dynamics from moving during age initilization 2022-05-30 14:22:12 -07:00
82159bcb4a Merge branch 'ticket/47' of https://foundry.openuru.org/gitblit/r/CWE-ou-minkata into ticket/47 2022-05-30 14:04:22 -07:00
b81eb21145 Fix compile error
Author: Adam Johnson <AdamJohnso@gmail.com>
2022-05-30 14:03:33 -07:00
e7b4f5c6ba Fix compile error
(cherry picked from commit 202e846a56)
2022-05-11 15:20:16 -06:00
202e846a56 Fix compile error 2022-05-11 14:16:44 -07:00
deb4858f3e Add subtitle and loc key message flags
(cherry picked from commit 126e7a76dd)
2022-05-11 13:58:51 -06:00
bff879abfd PR from Huru to prevent dynamics from moving during age initilization 2022-05-11 13:58:51 -06:00
fededb574b Change to prevent crashing when fCurStage is null 2022-05-11 13:58:51 -06:00
126e7a76dd Add subtitle and loc key message flags 2022-05-10 20:07:41 -05:00
26807a8d87 Merge branch 'ticket/47' 2022-05-05 09:45:42 -06:00
f54f14328e PR from Huru to prevent dynamics from moving during age initilization 2022-05-04 20:16:58 -07:00
311671e7a2 Merge branch 'ticket/46'
closes #46
2022-04-29 14:55:59 -06:00
8aaa98b8b7 Change to prevent crashing when fCurStage is null 2022-04-29 07:46:54 -07:00
3489e04463 Fix crash from plMouseDevice::HideCursor if it is called before cursor is created 2022-04-06 19:46:00 -05:00
33bbc490be Minor code quality correction 2022-04-06 19:32:30 -05:00
fd0c2a205e Fix nondeterministic conflicting page processing on startup 2022-04-06 19:18:05 -05:00
b2521e0777 Merge branch 'ticket/42'
closes #42
2022-03-23 09:22:29 -06:00
f9d629cfc5 Expand thread memory allocations for stack and heap to 1.25MB 2022-03-22 13:52:03 -06:00
13 changed files with 107 additions and 79 deletions

View File

@ -165,6 +165,8 @@ class pfKIMsg : public plMessage
kUNUSED1 = 0x00000008,
kStatusMsg = 0x00000010,
kNeighborMsg = 0x00000020, // sending to all the neighbors
kSubtitleMsg = 0x00000040,
kLocKeyMsg = 0x00000080,
kChannelMask = 0x0000ff00
};

View File

@ -474,6 +474,12 @@ void plPythonSDLModifier::IPythonVarToSDL(plStateDataRecord* state, const char*
int count = PyTuple_Size(pyVar);
plSimpleVarDescriptor::Type type = var->GetSimpleVarDescriptor()->GetType();
// Ensure that variable length arrays match.
if (var->GetSimpleVarDescriptor()->IsVariableLength()) {
if (var->GetCount() != count)
var->Alloc(count);
}
for (int i = 0; i < count; i++)
{
PyObject* pyVarItem = PyTuple_GetItem(pyVar, i);

View File

@ -326,7 +326,7 @@ bool plAvBrainClimb::IProcessExitStage(double time, float elapsed)
float curBlend = ai->GetBlend();
if(curBlend > .99) // reached peak strength
if(fCurStage && curBlend > .99) // reached peak strength
{
fCurStage->Detach(fAvMod); // remove the (now completely masked) underlying anim
fCurStage = nil;

View File

@ -481,8 +481,8 @@ void plMouseDevice::SetCursorY(hsScalar y)
void plMouseDevice::HideCursor(hsBool override)
{
if( fInstance->fCursor != nil )
fInstance->fCursor->SetVisible( false );
if (fInstance && fInstance->fCursor)
fInstance->fCursor->SetVisible(false);
plMouseDevice::bCursorOverride = (override != 0);
plMouseDevice::bCursorHidden = true;
@ -499,9 +499,11 @@ void plMouseDevice::ShowCursor(hsBool override)
plMouseDevice::bCursorHidden = false;
plMouseDevice::bCursorOverride = false;
if( fInstance->fCursor == nil )
fInstance->CreateCursor( fInstance->fCursorID );
fInstance->fCursor->SetVisible( true );
if (fInstance) {
if (!fInstance->fCursor)
fInstance->CreateCursor(fInstance->fCursorID);
fInstance->fCursor->SetVisible(true);
}
}
void plMouseDevice::NewCursor(char* cursor)

View File

@ -217,6 +217,8 @@ bool plResponderModifier::IIsLocalOnlyCmd(plMessage* cmd)
return true;
if (plCameraMsg::ConvertNoRef(cmd)) // don't want to change our camera
return true;
if (plSubWorldMsg::ConvertNoRef(cmd)) // don't want to enter a subworld (changes the avatar SDL)
return true;
plSoundMsg *snd = plSoundMsg::ConvertNoRef( cmd );
if( snd != nil && snd->Cmd( plSoundMsg::kIsLocalOnly ) )

View File

@ -211,7 +211,7 @@ void plNCAgeJoiner::Start () {
plNetClientMgr * nc = plNetClientMgr::GetInstance();
nc->SetFlagsBit(plNetClientMgr::kPlayingGame, false);
nc->fServerTimeOffset = 0; // reset since we're connecting to a new server
nc->ResetServerTimeOffset();
nc->fRequiredNumInitialSDLStates = 0;
nc->fNumInitialSDLStates = 0;
nc->SetFlagsBit(plNetClientApp::kNeedInitialAgeStateCount);

View File

@ -133,9 +133,7 @@ plNetClientMgr::plNetClientMgr() :
// fProgressBar( nil ),
fTaskProgBar( nil ),
fMsgRecorder(nil),
fServerTimeOffset(0),
fTimeSamples(0),
fLastTimeUpdate(0),
fLastLocalTime(),
fListenListMode(kListenList_Distance),
fAgeSDLObjectKey(nil),
fExperimentalLevel(0),
@ -480,34 +478,23 @@ void plNetClientMgr::StartLinkInFX()
//
void plNetClientMgr::UpdateServerTimeOffset(plNetMessage* msg)
{
if ((hsTimer::GetSysSeconds() - fLastTimeUpdate) > 5)
{
fLastTimeUpdate = hsTimer::GetSysSeconds();
if (!msg->GetHasTimeSent())
return;
if (msg->GetTimeSent().AtEpoch())
return;
const plUnifiedTime& msgSentUT = msg->GetTimeSent();
if (!msgSentUT.AtEpoch())
{
double diff = plUnifiedTime::GetTimeDifference(msgSentUT, plClientUnifiedTime::GetCurrentTime());
double localTime = hsTimer::GetSeconds();
if (localTime - fLastLocalTime < 1.0)
return;
if (fServerTimeOffset == 0)
{
fServerTimeOffset = diff;
}
else
{
fServerTimeOffset = fServerTimeOffset + ((diff - fServerTimeOffset) / ++fTimeSamples);
}
DebugMsg("Setting server time offset to %f", fServerTimeOffset);
}
}
fLastServerTime = msg->GetTimeSent();
fLastLocalTime = localTime;
}
void plNetClientMgr::ResetServerTimeOffset()
{
fServerTimeOffset = 0;
fTimeSamples = 0;
fLastTimeUpdate = 0;
fLastServerTime.ToEpoch();
fLastLocalTime = 0.0;
}
//
@ -515,14 +502,12 @@ void plNetClientMgr::ResetServerTimeOffset()
//
plUnifiedTime plNetClientMgr::GetServerTime() const
{
if ( fServerTimeOffset==0 ) // offline mode or before connecting/calibrating to a server
if (fLastServerTime.AtEpoch()) {
WarningMsg("Someone asked for the server time, but we don't know it yet!");
return plUnifiedTime::GetCurrentTime();
plUnifiedTime serverUT;
if (fServerTimeOffset<0)
return plUnifiedTime::GetCurrentTime() - plUnifiedTime(fabs(fServerTimeOffset));
else
return plUnifiedTime::GetCurrentTime() + plUnifiedTime(fServerTimeOffset);
}
return fLastServerTime + plUnifiedTime(hsTimer::GetSeconds() - fLastLocalTime);
}
//

View File

@ -166,9 +166,8 @@ private:
std::string fSPDesiredPlayerName; // SP: the player we want to load from vault.
// server info
double fServerTimeOffset; // diff between our unified time and server's unified time
UInt32 fTimeSamples;
double fLastTimeUpdate;
plUnifiedTime fLastServerTime; // Last received time update from the server
double fLastLocalTime; // Last monotonic time (in seconds) when the above update was received
UInt8 fJoinOrder; // returned by the server

View File

@ -1328,9 +1328,9 @@ void plPXPhysical::GetSyncState(hsPoint3& pos, hsQuat& rot, hsVector3& linV, hsV
void plPXPhysical::SetSyncState(hsPoint3* pos, hsQuat* rot, hsVector3* linV, hsVector3* angV)
{
bool initialSync = plNetClientApp::GetInstance()->IsLoadingInitialAgeState() &&
plNetClientApp::GetInstance()->GetJoinOrder() == 0;
bool isLoading = plNetClientApp::GetInstance()->IsLoadingInitialAgeState();
bool isFirstIn = plNetClientApp::GetInstance()->GetJoinOrder() == 0;
bool initialSync = isLoading && isFirstIn;
// If the physical has fallen out of the sim, and this is initial age state, and we're
// the first person in, reset it to the original position. (ie, prop the default state
// we've got right now)
@ -1350,6 +1350,13 @@ void plPXPhysical::SetSyncState(hsPoint3* pos, hsQuat* rot, hsVector3* linV, hsV
SetLinearVelocitySim(*linV);
if (angV)
SetAngularVelocitySim(*angV);
// If we're loading the age, then we should ensure the objects stay asleep if they're supposed to be asleep.
// NOTE: We should only do this if the objects are not at their initial locations. Otherwise, they might
// sleep inside each other and explode or float randomly in midair
if (isLoading && GetProperty(plSimulationInterface::kStartInactive) && !fActor->readBodyFlag(NX_BF_KINEMATIC)) {
if (!pos && !rot)
fActor->putToSleep();
}
SendNewLocation(false, true);
}

View File

@ -59,8 +59,10 @@ plRegistryKeyList::~plRegistryKeyList()
for (int i = 0; i < fStaticKeys.size(); i++)
{
plKeyImp* keyImp = fStaticKeys[i];
if (!keyImp->ObjectIsLoaded())
if (keyImp && !keyImp->ObjectIsLoaded()) {
fStaticKeys[i] = nullptr;
delete keyImp;
}
}
}

View File

@ -203,6 +203,7 @@ void plRegistryPageNode::UnloadKeys()
for (; it != fKeyLists.end(); it++)
{
plRegistryKeyList* keyList = it->second;
it->second = nullptr;
delete keyList;
}
fKeyLists.clear();

View File

@ -219,14 +219,20 @@ void plResManager::IShutdown()
// Shut down the registry (finally!)
ILockPages();
PageSet::const_iterator it;
for (it = fAllPages.begin(); it != fAllPages.end(); it++)
delete *it;
fAllPages.clear();
// Unload all keys before actually deleting the pages.
// When a key's refcount drops to zero, IKeyUnreffed looks up the key's page.
// If the page is already deleted at that point, this causes a use after free and potential crash.
for (PageSet::const_iterator it = fAllPages.begin(); it != fAllPages.end(); it++) {
(*it)->UnloadKeys();
}
fLoadedPages.clear();
fLastFoundPage = nil;
for (PageSet::const_iterator it = fAllPages.begin(); it != fAllPages.end(); it++) {
delete *it;
}
fAllPages.clear();
IUnlockPages();
fLastFoundPage = nil;
// Now, kill off the Dispatcher
hsRefCnt_SafeUnRef(fDispatch);
@ -1299,7 +1305,7 @@ void plResManager::PageInAge(const char *age)
hsBool plResManager::VerifyPages()
{
hsTArray<plRegistryPageNode*> invalidPages, newerPages;
PageSet invalidPages, newerPages;
// Step 1: verify major/minor version changes
if (plResMgrSettings::Get().GetFilterNewerPageVersions() ||
@ -1313,7 +1319,7 @@ hsBool plResManager::VerifyPages()
if (page->GetPageCondition() == kPageTooNew && plResMgrSettings::Get().GetFilterNewerPageVersions())
{
newerPages.Append(page);
newerPages.insert(page);
fAllPages.erase(page);
}
else if (
@ -1321,21 +1327,21 @@ hsBool plResManager::VerifyPages()
page->GetPageCondition() == kPageOutOfDate)
&& plResMgrSettings::Get().GetFilterOlderPageVersions())
{
invalidPages.Append(page);
invalidPages.insert(page);
fAllPages.erase(page);
}
}
}
// Handle all our invalid pages now
if (invalidPages.GetCount() > 0)
if (!invalidPages.empty())
{
if (!IDeleteBadPages(invalidPages, false))
return false;
}
// Warn about newer pages
if (newerPages.GetCount() > 0)
if (!newerPages.empty())
{
if (!IWarnNewerPages(newerPages))
return false;
@ -1343,22 +1349,35 @@ hsBool plResManager::VerifyPages()
// Step 2 of verification: make sure no sequence numbers conflict
PageSet::iterator it = fAllPages.begin();
for (; it != fAllPages.end(); it++)
for (; it != fAllPages.end();)
{
plRegistryPageNode* page = *it;
PageSet::iterator itUp = it;
itUp++;
for (; itUp != fAllPages.end(); itUp++)
bool amValid = true;
for (; itUp != fAllPages.end();)
{
plRegistryPageNode* upPage = *itUp;
if (page->GetPageInfo().GetLocation() == upPage->GetPageInfo().GetLocation())
{
invalidPages.Append(upPage);
fAllPages.erase(itUp);
break;
if (page->GetPageInfo().GetLocation() == upPage->GetPageInfo().GetLocation()) {
invalidPages.insert(upPage);
itUp = fAllPages.erase(itUp);
amValid = false;
} else {
itUp++;
}
}
// Delete *all* conflicting pages, not just conflicting - 1.
// If we leave in a single conflicting page, a new conflict can trivially
// be introduced if the page we leave behind is defunct and a new version
// is later downloaded from the FileSrv.
if (!amValid) {
invalidPages.insert(page);
it = fAllPages.erase(it);
} else {
it++;
}
}
// Redo our loaded pages list, since Verify() might force the page's keys to load or unload
@ -1374,7 +1393,7 @@ hsBool plResManager::VerifyPages()
}
// Handle all our conflicting pages now
if (invalidPages.GetCount() > 0)
if (!invalidPages.empty())
return IDeleteBadPages(invalidPages, true);
return true;
@ -1384,9 +1403,10 @@ hsBool plResManager::VerifyPages()
// Given an array of pages that are invalid (major version out-of-date or
// whatnot), asks the user what we should do about them.
static void ICatPageNames(hsTArray<plRegistryPageNode*>& pages, char* buf, int bufSize)
static void ICatPageNames(const std::set<plRegistryPageNode*>& pages, char* buf, int bufSize)
{
for (int i = 0; i < pages.GetCount(); i++)
int i = 0;
for (auto it = pages.cbegin(); it != pages.cend(); ++it, ++i)
{
if (i >= 25)
{
@ -1394,7 +1414,7 @@ static void ICatPageNames(hsTArray<plRegistryPageNode*>& pages, char* buf, int b
break;
}
const char* pagePath = pages[i]->GetPagePath();
const char* pagePath = (*it)->GetPagePath();
const char* pageFile = plFileUtils::GetFileName(pagePath);
if (strlen(buf) + strlen(pageFile) > bufSize - 5)
@ -1408,7 +1428,7 @@ static void ICatPageNames(hsTArray<plRegistryPageNode*>& pages, char* buf, int b
}
}
hsBool plResManager::IDeleteBadPages(hsTArray<plRegistryPageNode*>& invalidPages, hsBool conflictingSeqNums)
hsBool plResManager::IDeleteBadPages(PageSet& invalidPages, hsBool conflictingSeqNums)
{
#ifndef PLASMA_EXTERNAL_RELEASE
if (!hsMessageBox_SuppressPrompts)
@ -1430,12 +1450,12 @@ hsBool plResManager::IDeleteBadPages(hsTArray<plRegistryPageNode*>& invalidPages
#endif // PLASMA_EXTERNAL_RELEASE
// Delete 'em
for (int i = 0; i < invalidPages.GetCount(); i++)
for (PageSet::iterator it = invalidPages.begin(); it != invalidPages.end(); ++it)
{
invalidPages[i]->DeleteSource();
delete invalidPages[i];
(*it)->DeleteSource();
delete *it;
}
invalidPages.Reset();
invalidPages.clear();
fLastFoundPage = nil;
@ -1447,7 +1467,7 @@ hsBool plResManager::IDeleteBadPages(hsTArray<plRegistryPageNode*>& invalidPages
// than the "current" one), warns the user about them but does nothing to
// them.
hsBool plResManager::IWarnNewerPages(hsTArray<plRegistryPageNode*> &newerPages)
hsBool plResManager::IWarnNewerPages(PageSet &newerPages)
{
#ifndef PLASMA_EXTERNAL_RELEASE
if (!hsMessageBox_SuppressPrompts)
@ -1465,9 +1485,9 @@ hsBool plResManager::IWarnNewerPages(hsTArray<plRegistryPageNode*> &newerPages)
// Not deleting the files, just delete them from memory
for (int i = 0; i < newerPages.GetCount(); i++)
delete newerPages[i];
newerPages.Reset();
for (PageSet::iterator it = newerPages.begin(); it != newerPages.end(); ++it)
delete *it;
newerPages.clear();
fLastFoundPage = nil;

View File

@ -61,6 +61,9 @@ typedef void(*plProgressProc)(plKey key);
class plResManager : public hsResMgr
{
protected:
typedef std::set<plRegistryPageNode*> PageSet;
public:
plResManager();
virtual ~plResManager();
@ -194,8 +197,8 @@ protected:
void IUnloadPageKeys(plRegistryPageNode* pageNode, hsBool dontClear = false);
hsBool IDeleteBadPages(hsTArray<plRegistryPageNode*>& invalidPages, hsBool conflictingSeqNums);
hsBool IWarnNewerPages(hsTArray<plRegistryPageNode*>& newerPages);
hsBool IDeleteBadPages(PageSet& invalidPages, hsBool conflictingSeqNums);
hsBool IWarnNewerPages(PageSet& newerPages);
void ILockPages();
void IUnlockPages();
@ -233,7 +236,6 @@ protected:
UInt8 fPageListLock; // Number of locks on the page lists. If it's greater than zero, they can't be modified
hsBool fPagesNeedCleanup; // True if something modified the page lists while they were locked.
typedef std::set<plRegistryPageNode*> PageSet;
PageSet fAllPages; // All the pages, loaded or not
PageSet fLoadedPages; // Just the loaded pages