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

..

102 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
1f7de46bc2 Expand thread memory allocations for stack and heap to 1.25MB 2022-03-22 13:53:50 -06:00
f9d629cfc5 Expand thread memory allocations for stack and heap to 1.25MB 2022-03-22 13:52:03 -06:00
b16de9d86f Merge branch 'master' into working 2022-03-19 21:41:37 -06:00
aba5e2562c Merge branch 'ticket/38'
closes #38
2022-03-19 21:39:41 -06:00
bff8203fbe Merge branch 'ticket/38' of https://foundry.openuru.org/gitblit/r/CWE-ou-minkata into ticket/38 2022-03-19 22:15:28 -05:00
23ded3210f By popular demand, enable subtitles by default 2022-03-19 22:15:14 -05:00
bbeb25d29a Merge branch 'master' into working 2022-03-12 09:16:15 -07:00
9f9d510958 Merge branch 'ticket/38'
closes #38
2022-03-12 09:15:42 -07:00
f0d2bd3eaa Don't feed remaining subtitles when audio skips to past the end of last subtitle
(cherry picked from commit 40bcaba9d8)
2022-03-11 10:05:46 -07:00
41627d1c7c Merge branch 'master' into working 2022-03-11 10:03:31 -07:00
ea4bb43623 Merge branch 'ticket/38' of https://foundry.openuru.org/gitblit/r/CWE-ou-minkata into ticket/38 2022-03-11 10:59:08 -06:00
40bcaba9d8 Don't feed remaining subtitles when audio skips to past the end of last subtitle 2022-03-11 10:55:44 -06:00
e93db035ba Revert "Fixes bug where avatar run-lock state can get confused after alt-tabbing"
This reverts commit 69dac251b6.
2022-03-09 09:44:05 -07:00
94fab5996f Merge branch 'ticket/41'
closes #41
2022-03-09 09:42:23 -07:00
da7d2d0e5c Merge branch 'ticket/40'
closes #40
2022-03-09 09:41:57 -07:00
2e8dc81bf3 Merge branch 'ticket/38'
closes #38
2022-03-09 09:41:29 -07:00
c0e83259f3 Don't display previous subtitles all at once when subtitles are enabled mid-audio play
(cherry picked from commit 40f200e066)
2022-03-06 10:17:51 -07:00
838e3e51ad Merge branch 'ticket/38' of https://foundry.openuru.org/gitblit/r/CWE-ou-minkata into ticket/38 2022-03-06 09:10:38 -06:00
40f200e066 Don't display previous subtitles all at once when subtitles are enabled mid-audio play 2022-03-06 09:04:27 -06:00
6e4996e1be Ensure pyGUIControlListBox::GetElementW can't attempt to return a null pointer as a std::wstring
(cherry picked from commit 2f1bb87056)
2022-03-05 12:42:42 -07:00
2f1bb87056 Ensure pyGUIControlListBox::GetElementW can't attempt to return a null pointer as a std::wstring 2022-03-05 13:34:52 -06:00
df848b48c4 Prevent deferred link race conditions
(cherry picked from commit e512dd0c68)
2022-03-04 13:16:31 -07:00
75c570877a Merge branch 'master' into working 2022-03-04 13:16:11 -07:00
e512dd0c68 Prevent deferred link race conditions 2022-03-03 23:26:08 -06:00
4c76549fb3 Merge branch 'ticket/33'
closes #33
2022-03-01 14:42:05 -07:00
1a930cb47f Merge branch 'ticket/38'
closes #38
2022-03-01 11:02:25 -07:00
b9af23e458 Merge branch 'ticket/37'
closes #37
2022-03-01 11:02:04 -07:00
9e2e2d02e1 Merge branch 'ticket/36'
closes #36
2022-03-01 11:01:42 -07:00
7a73c2d8e3 Merge branch 'ticket/34'
closes #34
2022-03-01 11:01:03 -07:00
933cbe2fe7 Merge branch 'ticket/32'
closes #32
2022-03-01 11:00:22 -07:00
fe88f2e8a2 Merge branch 'ticket/31'
closes #31
2022-03-01 10:59:54 -07:00
9e308cbebe Fix another log string formatting issue found by Adam. 2022-02-26 20:22:41 -06:00
126d7511e0 Fix parentheses mistake for retrieving streaming audio timings and apply code fix suggestions from Adam 2022-02-26 19:16:00 -06:00
64323c6073 Apply code suggestions from rarified 2022-02-26 11:57:56 -06:00
8a2534dff6 Simplify SRT file path construction with suggestion from Hoikas 2022-02-25 14:34:30 -06:00
9a1b37e7f6 Turn std::strings into char* before doing PyObject_CallMethod with them 2022-02-25 12:14:44 -06:00
1012251d9a Add missing message dispatch registration 2022-02-25 01:07:40 -06:00
1d65c78097 Fix bad include, missing static declaration, SRT path directory, and formatting 2022-02-25 01:06:29 -06:00
c50bb08e8d Fix usage and overflow bug causing plWin32StreamingSound::GetActualTimeSec() to return absurd values. Needed fix for subtitle timings. 2022-02-23 21:46:02 -06:00
229883654e Initial pass at getting subtitle support in. Doesn't compile for unknown reasons 2022-02-23 21:35:03 -06:00
51b6b4750b Don't update to visible arrow when cursor should be hidden 2022-02-18 20:19:15 -06:00
69dac251b6 Fixes bug where avatar run-lock state can get confused after alt-tabbing 2022-02-18 18:11:37 -06:00
e81af06584 Fix error due to no Empty() 2022-01-24 19:06:23 -08:00
5f3a8644a7 Files for Allowing disabling avatar panic links 2022-01-24 14:22:04 -08:00
62089be53f Changes needed so climbing works correctly with wall 2022-01-07 11:31:11 -08:00
391bbaa4e7 Update error messages for new variable 2021-12-15 09:23:54 -08:00
b00c7729cc Ensure we don't try to get localized values for null objectnames 2021-12-03 20:08:31 -06:00
21 changed files with 188 additions and 104 deletions

View File

@ -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>

View File

@ -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;

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

@ -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"";
}

View File

@ -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;

View File

@ -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();
}
}
}
}
}

View File

@ -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;
}

View File

@ -95,6 +95,7 @@ public:
void AdvanceToTime(uint32_t timeMs);
plSrtEntry* GetNextEntryStartingBeforeTime(uint32_t timeMs);
plSrtEntry* GetNextEntryEndingBeforeTime(uint32_t timeMs);
uint32_t GetLastEntryEndTime();
protected:

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

@ -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)

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

@ -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;
}

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