mirror of
https://foundry.openuru.org/gitblit/r/CWE-ou-minkata.git
synced 2025-07-15 10:54:18 +00:00
Compare commits
102 Commits
working_su
...
OPENURU_BU
Author | SHA1 | Date | |
---|---|---|---|
883495c35c | |||
e1306da736 | |||
8d1d813df5 | |||
65d50895bb | |||
6a41bdbee7 | |||
3dcf1c2f26 | |||
70449244f4 | |||
82abcb2f07 | |||
870d0534df | |||
1f09d6c48a | |||
66ce08ed67 | |||
1c1d3dd82e | |||
4924156ad4 | |||
13ea0a98de | |||
f9723462d7 | |||
7d3774a732 | |||
ea7e4b2ab5 | |||
5d5ba00f7d | |||
af38137822 | |||
4b0ab75a79 | |||
dcb0309a08 | |||
7dde0855dc | |||
44c9b0694d | |||
dedf04ac43 | |||
eeb458817f | |||
68c7187155 | |||
6fa695a2c3 | |||
2a3c1b32ef | |||
d3cbaa94ef | |||
e7758ccc10 | |||
07b92234ad | |||
7dfa2ba56a | |||
1a091b7019 | |||
104a5ef4ee | |||
19cfaaaea9 | |||
dafd190083 | |||
fdee5a921b | |||
b322ee094c | |||
54c768d966 | |||
82159bcb4a | |||
b81eb21145 | |||
e7b4f5c6ba | |||
202e846a56 | |||
deb4858f3e | |||
bff879abfd | |||
fededb574b | |||
126e7a76dd | |||
26807a8d87 | |||
f54f14328e | |||
311671e7a2 | |||
8aaa98b8b7 | |||
3489e04463 | |||
33bbc490be | |||
fd0c2a205e | |||
b2521e0777 | |||
1f7de46bc2 | |||
f9d629cfc5 | |||
b16de9d86f | |||
aba5e2562c | |||
bff8203fbe | |||
23ded3210f | |||
bbeb25d29a | |||
9f9d510958 | |||
f0d2bd3eaa | |||
41627d1c7c | |||
ea4bb43623 | |||
40bcaba9d8 | |||
e93db035ba | |||
94fab5996f | |||
da7d2d0e5c | |||
2e8dc81bf3 | |||
c0e83259f3 | |||
838e3e51ad | |||
40f200e066 | |||
6e4996e1be | |||
2f1bb87056 | |||
df848b48c4 | |||
75c570877a | |||
e512dd0c68 | |||
4c76549fb3 | |||
1a930cb47f | |||
b9af23e458 | |||
9e2e2d02e1 | |||
7a73c2d8e3 | |||
933cbe2fe7 | |||
fe88f2e8a2 | |||
9e308cbebe | |||
126d7511e0 | |||
64323c6073 | |||
8a2534dff6 | |||
9a1b37e7f6 | |||
1012251d9a | |||
1d65c78097 | |||
c50bb08e8d | |||
229883654e | |||
51b6b4750b | |||
69dac251b6 | |||
e81af06584 | |||
5f3a8644a7 | |||
62089be53f | |||
391bbaa4e7 | |||
b00c7729cc |
@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug_Internal|Win32">
|
||||
@ -121,6 +121,8 @@
|
||||
<MapFileName>$(OutDir)$(TargetName).map</MapFileName>
|
||||
<MapExports>true</MapExports>
|
||||
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
|
||||
<HeapReserveSize>0x140000</HeapReserveSize>
|
||||
<StackReserveSize>0x140000</StackReserveSize>
|
||||
</Link>
|
||||
<Midl>
|
||||
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
@ -177,6 +179,8 @@
|
||||
<MapFileName>$(OutDir)$(TargetName).map</MapFileName>
|
||||
<MapExports>true</MapExports>
|
||||
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
|
||||
<HeapReserveSize>0x140000</HeapReserveSize>
|
||||
<StackReserveSize>0x140000</StackReserveSize>
|
||||
</Link>
|
||||
<Midl>
|
||||
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
@ -237,6 +241,8 @@
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
<MapExports>true</MapExports>
|
||||
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
|
||||
<HeapReserveSize>0x140000</HeapReserveSize>
|
||||
<StackReserveSize>0x140000</StackReserveSize>
|
||||
</Link>
|
||||
<Midl>
|
||||
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
@ -298,6 +304,8 @@
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
<MapExports>true</MapExports>
|
||||
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
|
||||
<HeapReserveSize>0x140000</HeapReserveSize>
|
||||
<StackReserveSize>0x140000</StackReserveSize>
|
||||
</Link>
|
||||
<Midl>
|
||||
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
@ -802,4 +810,4 @@
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
</Project>
|
@ -2313,7 +2313,7 @@ void plClient::IDetectAudioVideoSettings()
|
||||
WriteInt(stream, "Audio.SetChannelVolume Ambience", 1);
|
||||
WriteInt(stream, "Audio.SetChannelVolume NPCVoice", 1);
|
||||
WriteInt(stream, "Audio.EnableVoiceRecording", 1);
|
||||
WriteInt(stream, "Audio.EnableSubtitles", false);
|
||||
WriteInt(stream, "Audio.EnableSubtitles", true);
|
||||
WriteString(stream, "Audio.SetDeviceName", deviceName );
|
||||
stream->Close();
|
||||
delete stream;
|
||||
|
@ -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
|
||||
};
|
||||
|
||||
|
@ -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);
|
||||
|
@ -587,16 +587,17 @@ std::wstring pyGUIControlListBox::GetElementW( UInt16 idx )
|
||||
{
|
||||
// if its a text element type then it should be safe to cast it to a pfGUIListText
|
||||
pfGUIListText* letext = (pfGUIListText*)le;
|
||||
return letext->GetText();
|
||||
return (letext->GetText() != nullptr) ? letext->GetText() : L"";
|
||||
}
|
||||
else if ( le->GetType() == pfGUIListElement::kTreeRoot )
|
||||
{
|
||||
pfGUIListTreeRoot* elroot = (pfGUIListTreeRoot*)le;
|
||||
return elroot->GetTitle();
|
||||
return (elroot->GetTitle() != nullptr) ? elroot->GetTitle() : L"";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return L"";
|
||||
}
|
||||
|
||||
|
@ -994,7 +994,7 @@ hsBool plgAudioSys::fInit = false;
|
||||
hsBool plgAudioSys::fActive = false;
|
||||
hsBool plgAudioSys::fUseHardware = false;
|
||||
hsBool plgAudioSys::fMuted = true;
|
||||
bool plgAudioSys::fEnableSubtitles = false;
|
||||
bool plgAudioSys::fEnableSubtitles = true;
|
||||
hsBool plgAudioSys::fDelayedActivate = false;
|
||||
hsBool plgAudioSys::fEnableEAX = false;
|
||||
hsWindowHndl plgAudioSys::fWnd = nil;
|
||||
|
@ -111,14 +111,18 @@ void plWin32Sound::IFreeBuffers( void )
|
||||
void plWin32Sound::Update()
|
||||
{
|
||||
plSoundBuffer* buf = GetDataBuffer();
|
||||
if (plgAudioSys::AreSubtitlesEnabled() && buf != nullptr) {
|
||||
if (buf != nullptr) {
|
||||
plSrtFileReader* srtReader = buf->GetSrtReader();
|
||||
if (srtReader != nullptr) {
|
||||
uint32_t currentTimeMs = (uint32_t)(GetActualTimeSec() * 1000.0f);
|
||||
while (plSrtEntry* nextEntry = srtReader->GetNextEntryStartingBeforeTime(currentTimeMs)) {
|
||||
// add a plSubtitleMsg to go... to whoever is listening (probably the KI)
|
||||
plSubtitleMsg* msg = new plSubtitleMsg(nextEntry->GetSubtitleText(), nextEntry->GetSpeakerName());
|
||||
msg->Send();
|
||||
if (currentTimeMs <= srtReader->GetLastEntryEndTime()) {
|
||||
while (plSrtEntry* nextEntry = srtReader->GetNextEntryStartingBeforeTime(currentTimeMs)) {
|
||||
if (plgAudioSys::AreSubtitlesEnabled()) {
|
||||
// add a plSubtitleMsg to go... to whoever is listening (probably the KI)
|
||||
plSubtitleMsg* msg = new plSubtitleMsg(nextEntry->GetSubtitleText(), nextEntry->GetSpeakerName());
|
||||
msg->Send();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -184,4 +184,13 @@ plSrtEntry* plSrtFileReader::GetNextEntryEndingBeforeTime(uint32_t timeMs)
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
uint32_t plSrtFileReader::GetLastEntryEndTime()
|
||||
{
|
||||
if (!fEntries.empty()) {
|
||||
return fEntries.back().GetEndTimeMs();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
@ -95,6 +95,7 @@ public:
|
||||
void AdvanceToTime(uint32_t timeMs);
|
||||
plSrtEntry* GetNextEntryStartingBeforeTime(uint32_t timeMs);
|
||||
plSrtEntry* GetNextEntryEndingBeforeTime(uint32_t timeMs);
|
||||
uint32_t GetLastEntryEndTime();
|
||||
|
||||
protected:
|
||||
|
||||
|
@ -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;
|
||||
|
@ -176,16 +176,19 @@ void plKeyboardDevice::HandleKeyEvent(plOSMsg message, plKeyDef key, bool bKeyDo
|
||||
if (key == KEY_SHIFT)
|
||||
{
|
||||
fShiftKeyDown = bKeyDown;
|
||||
// return;
|
||||
}
|
||||
if (key == KEY_CTRL)
|
||||
{
|
||||
fCtrlKeyDown = bKeyDown;
|
||||
// return;
|
||||
}
|
||||
if (key == KEY_CAPSLOCK)
|
||||
{
|
||||
if (!bKeyRepeat)
|
||||
// Keyboards toggle the light on key-down, so I'm going with that.
|
||||
if (bKeyDown && !bKeyRepeat)
|
||||
{
|
||||
fCapsLockLock = (GetKeyState(KEY_CAPSLOCK) & 1) == 1;
|
||||
fCapsLockLock = !fCapsLockLock;
|
||||
plAvatarInputInterface::GetInstance()->ForceAlwaysRun(fCapsLockLock);
|
||||
}
|
||||
}
|
||||
@ -205,8 +208,7 @@ void plKeyboardDevice::HandleWindowActivate(bool bActive, HWND hWnd)
|
||||
{
|
||||
if (bActive)
|
||||
{
|
||||
// Refresh the caps lock state
|
||||
HandleKeyEvent(KEYDOWN, KEY_CAPSLOCK, nil, false);
|
||||
fCtrlKeyDown = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -479,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;
|
||||
@ -497,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)
|
||||
|
@ -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 ) )
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -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
|
||||
|
||||
|
@ -504,25 +504,56 @@ bool plNetLinkingMgr::IProcessVaultNotifyMsg(plVaultNotifyMsg* msg)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (cVaultLink != nil)
|
||||
{
|
||||
// This is something that Cyan does... >.<
|
||||
// It's very useful though...
|
||||
if (cVaultLink != nil) {
|
||||
// Verify that if the Age vault already exists that it matches the requested
|
||||
// deferred link. If it doesn't exist, well, I hope you're happy with the result.
|
||||
VaultAgeLinkNode accLink(cVaultLink);
|
||||
accLink.CopyTo(cur);
|
||||
if (RelVaultNode* rvnInfo = cVaultLink->GetChildNodeIncRef(plVault::kNodeType_AgeInfo, 1))
|
||||
{
|
||||
if (RelVaultNode* rvnInfo = cVaultLink->GetChildNodeIncRef(plVault::kNodeType_AgeInfo, 1)) {
|
||||
plAgeInfoStruct dest;
|
||||
|
||||
VaultAgeInfoNode accInfo(rvnInfo);
|
||||
accInfo.CopyTo(cur->GetAgeInfo());
|
||||
accInfo.CopyTo(&dest);
|
||||
if (!dest.IsEqualTo(fDeferredLink->GetAgeLink()->GetAgeInfo())) {
|
||||
hsLogEntry(
|
||||
plNetClientMgr::GetInstance()->DebugMsg(
|
||||
"Waiting for a deferred link to '%s' but got AgeInfo for '%s' instead.",
|
||||
fDeferredLink->GetAgeLink()->AsStdString().c_str(),
|
||||
dest.AsStdString().c_str()
|
||||
);
|
||||
);
|
||||
|
||||
rvnInfo->DecRef();
|
||||
return false;
|
||||
}
|
||||
|
||||
rvnInfo->DecRef();
|
||||
}
|
||||
|
||||
// If we're still here, that means the links match. Set the vault copy as our current
|
||||
// AgeLink and AgeInfo. Note this mainly copies the AgeInfo.
|
||||
accLink.CopyTo(cur);
|
||||
hsLogEntry(
|
||||
plNetClientMgr::GetInstance()->DebugMsg(
|
||||
"Performing deferred link to '%s'",
|
||||
cur->AsStdString().c_str()
|
||||
);
|
||||
);
|
||||
|
||||
// Steals fDeferredLink
|
||||
IDoLink(fDeferredLink);
|
||||
fDeferredLink = nil;
|
||||
return true;
|
||||
|
||||
cVaultLink->DecRef();
|
||||
}
|
||||
|
||||
return true;
|
||||
} else {
|
||||
hsLogEntry(
|
||||
plNetClientMgr::GetInstance()->ErrorMsg(
|
||||
"Waiting for a deferred link to '%s' but got a garbage link?",
|
||||
fDeferredLink->GetAgeLink()->AsStdString().c_str()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -203,6 +203,7 @@ void plRegistryPageNode::UnloadKeys()
|
||||
for (; it != fKeyLists.end(); it++)
|
||||
{
|
||||
plRegistryKeyList* keyList = it->second;
|
||||
it->second = nullptr;
|
||||
delete keyList;
|
||||
}
|
||||
fKeyLists.clear();
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
Reference in New Issue
Block a user