Reconstruct readable C++ and organize cohesive source subsystems
Administrative source import: native x86 compilation passed for 423 authored units. Source placement and submission states are migrated separately; this commit does not imply peer acceptance.
Previous head: 35d2a8cb36
Payload SHA256: 592f016d2730c5593bb653aa054c1e5f76a6df72c8f5a09e66f74876e2e33dee
This commit is contained in:
parent
35d2a8cb36
commit
a47d20f8be
890 changed files with 11796 additions and 16664 deletions
|
|
@ -4,7 +4,7 @@ NamespaceIndentation: All
|
|||
FixNamespaceComments: false
|
||||
TabWidth: 2
|
||||
UseTab: Never
|
||||
ColumnLimit: 120
|
||||
ColumnLimit: 160
|
||||
AlignAfterOpenBracket: BlockIndent
|
||||
ContinuationIndentWidth: 2
|
||||
AlwaysBreakAfterReturnType: None
|
||||
|
|
@ -12,7 +12,7 @@ BreakBeforeBraces: Custom
|
|||
BraceWrapping:
|
||||
AfterFunction: false
|
||||
AllowShortIfStatementsOnASingleLine: Never
|
||||
InsertBraces: true
|
||||
InsertBraces: false
|
||||
AllowShortLoopsOnASingleLine: false
|
||||
AllowShortFunctionsOnASingleLine: None
|
||||
AllowShortBlocksOnASingleLine: Never
|
||||
|
|
@ -21,25 +21,13 @@ SpaceBeforeParens: Custom
|
|||
SpaceBeforeParensOptions:
|
||||
AfterControlStatements: true
|
||||
AfterFunctionDefinitionName: false
|
||||
BinPackParameters: false
|
||||
AllowAllParametersOfDeclarationOnNextLine: false
|
||||
PenaltyBreakBeforeFirstCallParameter: 0
|
||||
BinPackArguments: true
|
||||
BinPackParameters: BinPack
|
||||
AllowAllParametersOfDeclarationOnNextLine: true
|
||||
PenaltyBreakBeforeFirstCallParameter: 19
|
||||
PointerAlignment: Left
|
||||
# Include sorting:
|
||||
# 1. pch (must stay first) 2. other WoW.exe project headers
|
||||
# 3. generated gen/ headers 4. system <...> headers
|
||||
# Each group is alphabetised; Regroup re-buckets across blank lines.
|
||||
# IncludeIsMainRegex is set to never match so no header is auto-pinned above pch
|
||||
# (clang-format otherwise forces the "main" header to the very top).
|
||||
SortIncludes: CaseSensitive
|
||||
IncludeBlocks: Regroup
|
||||
IncludeIsMainRegex: "(WILL_NEVER_MATCH_zzz)$"
|
||||
IncludeCategories:
|
||||
- Regex: '^"pch(-impl)?\.h"'
|
||||
Priority: 1
|
||||
- Regex: '^"gen/'
|
||||
Priority: 3
|
||||
- Regex: '^<'
|
||||
Priority: 4
|
||||
- Regex: '^"'
|
||||
Priority: 2
|
||||
BreakStringLiterals: false
|
||||
ReflowComments: Never
|
||||
MaxEmptyLinesToKeep: 1
|
||||
SortIncludes: Never
|
||||
IncludeBlocks: Preserve
|
||||
|
|
|
|||
757
CMakeLists.txt
757
CMakeLists.txt
|
|
@ -10,12 +10,12 @@ add_subdirectory(ThirdParty)
|
|||
add_library(RagnarokUtility STATIC
|
||||
Source/Utility/XorBytes.cpp
|
||||
Source/Utility/Base64.cpp
|
||||
Source/Utility/GroupedInteger.cpp
|
||||
Source/Utility/LanguageCharset.cpp
|
||||
Source/Utility/ClientAngles.cpp
|
||||
Source/Utility/AffineMatrix.cpp
|
||||
Source/Utility/AffineLookAt.cpp
|
||||
Source/Utility/RayTriangle.cpp
|
||||
Source/Utility/Text/GroupedInteger.cpp
|
||||
Source/Utility/Text/LanguageCharset.cpp
|
||||
Source/Utility/Math/ClientAngles.cpp
|
||||
Source/Utility/Math/AffineMatrix.cpp
|
||||
Source/Utility/Math/AffineLookAt.cpp
|
||||
Source/Utility/Math/RayTriangle.cpp
|
||||
Source/Utility/Rijndael.cpp
|
||||
)
|
||||
|
||||
|
|
@ -28,21 +28,21 @@ set_target_properties(RagnarokUtility PROPERTIES CXX_EXTENSIONS OFF)
|
|||
if(WIN32)
|
||||
target_sources(RagnarokUtility PRIVATE
|
||||
Source/Utility/GuidParse.cpp
|
||||
Source/Utility/NSyncObject.cpp
|
||||
Source/Utility/CSyncObject.cpp
|
||||
Source/Utility/NThread.cpp
|
||||
Source/Utility/NMessageQueue.cpp
|
||||
Source/Utility/NMessageMgr.cpp
|
||||
Source/Utility/NObject.cpp
|
||||
Source/Utility/NRecycleObject.cpp
|
||||
Source/Utility/NRecycleObjectPoolMgr.cpp
|
||||
Source/Utility/NAsyncWork.cpp
|
||||
Source/Utility/NAsyncWorkQueue.cpp
|
||||
Source/Utility/NAsyncWorkThread.cpp
|
||||
Source/Utility/NAsyncWorkMgr.cpp
|
||||
Source/Utility/AsyncDiagnostic.cpp
|
||||
Source/Utility/Threading/NSyncObject.cpp
|
||||
Source/Utility/Threading/CSyncObject.cpp
|
||||
Source/Utility/Threading/NThread.cpp
|
||||
Source/Utility/Async/NMessageQueue.cpp
|
||||
Source/Utility/Async/NMessageMgr.cpp
|
||||
Source/Utility/Async/NObject.cpp
|
||||
Source/Utility/Async/NRecycleObject.cpp
|
||||
Source/Utility/Async/NRecycleObjectPoolMgr.cpp
|
||||
Source/Utility/Async/NAsyncWork.cpp
|
||||
Source/Utility/Async/NAsyncWorkQueue.cpp
|
||||
Source/Utility/Async/NAsyncWorkThread.cpp
|
||||
Source/Utility/Async/NAsyncWorkMgr.cpp
|
||||
Source/Utility/Async/AsyncDiagnostic.cpp
|
||||
Source/Contents/InstantVar.cpp
|
||||
Source/Utility/FormatString.cpp
|
||||
Source/Utility/Text/FormatString.cpp
|
||||
)
|
||||
target_compile_definitions(RagnarokUtility PUBLIC
|
||||
WIN32_LEAN_AND_MEAN NOMINMAX _ITERATOR_DEBUG_LEVEL=0
|
||||
|
|
@ -69,31 +69,32 @@ if(WIN32)
|
|||
set_target_properties(RagnarokArchive PROPERTIES CXX_EXTENSIONS OFF)
|
||||
|
||||
add_library(RagnarokClientStartup STATIC
|
||||
Source/Client/Launcher.cpp
|
||||
Source/Client/ApplicationWindow.cpp
|
||||
Source/Client/ErrorDialog.cpp
|
||||
Source/Client/UnhandledExceptionHandler.cpp
|
||||
Source/Client/ModeCursor.cpp
|
||||
Source/Client/Mouse.cpp
|
||||
Source/Client/Application/Launcher.cpp
|
||||
Source/Client/Application/ApplicationWindow.cpp
|
||||
Source/Client/Application/ErrorDialog.cpp
|
||||
Source/Client/Application/UnhandledExceptionHandler.cpp
|
||||
Source/Client/Mode/ModeCursor.cpp
|
||||
Source/Client/Mode/ActiveGameMode.cpp
|
||||
Source/Client/Input/Mouse.cpp
|
||||
Source/Client/ClientOptions.cpp
|
||||
Source/Client/TextInputBuffer.cpp
|
||||
Source/Client/ImeInput.cpp
|
||||
Source/Client/TraditionalKeyInput.cpp
|
||||
Source/Client/InputCharset.cpp
|
||||
Source/Client/BrowserWindowSizing.cpp
|
||||
Source/Client/BrowserInterface.cpp
|
||||
Source/Client/BrowserCursor.cpp
|
||||
Source/Client/BrowserAddressEdit.cpp
|
||||
Source/Client/BrowserHostWindow.cpp
|
||||
Source/Client/BrowserCommandTarget.cpp
|
||||
Source/Client/BrowserInPlace.cpp
|
||||
Source/Client/BrowserDocumentUI.cpp
|
||||
Source/Client/BrowserClientSite.cpp
|
||||
Source/Client/BrowserAddressBar.cpp
|
||||
Source/Client/BrowserFrame.cpp
|
||||
Source/Client/BrowserSiteAttachment.cpp
|
||||
Source/Client/BrowserClose.cpp
|
||||
Source/Client/BrowserCreation.cpp
|
||||
Source/Client/Input/TextInputBuffer.cpp
|
||||
Source/Client/Input/ImeInput.cpp
|
||||
Source/Client/Input/TraditionalKeyInput.cpp
|
||||
Source/Client/Input/InputCharset.cpp
|
||||
Source/Client/Browser/BrowserWindowSizing.cpp
|
||||
Source/Client/Browser/BrowserInterface.cpp
|
||||
Source/Client/Browser/BrowserCursor.cpp
|
||||
Source/Client/Browser/BrowserAddressEdit.cpp
|
||||
Source/Client/Browser/BrowserHostWindow.cpp
|
||||
Source/Client/Browser/BrowserCommandTarget.cpp
|
||||
Source/Client/Browser/BrowserInPlace.cpp
|
||||
Source/Client/Browser/BrowserDocumentUI.cpp
|
||||
Source/Client/Browser/BrowserClientSite.cpp
|
||||
Source/Client/Browser/BrowserAddressBar.cpp
|
||||
Source/Client/Browser/BrowserFrame.cpp
|
||||
Source/Client/Browser/BrowserSiteAttachment.cpp
|
||||
Source/Client/Browser/BrowserClose.cpp
|
||||
Source/Client/Browser/BrowserCreation.cpp
|
||||
)
|
||||
target_include_directories(RagnarokClientStartup PUBLIC
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/Source"
|
||||
|
|
@ -104,74 +105,74 @@ if(WIN32)
|
|||
set_target_properties(RagnarokClientStartup PROPERTIES CXX_EXTENSIONS OFF)
|
||||
|
||||
add_library(RagnarokRender STATIC
|
||||
Source/Render/RenderPrimitive.cpp
|
||||
Source/Render/RenderPrimitivePool.cpp
|
||||
Source/Render/RenderCommandPool.cpp
|
||||
Source/Render/LightmappedPrimitive.cpp
|
||||
Source/Render/DepthAlpha.cpp
|
||||
Source/Render/RenderVertexPool.cpp
|
||||
Source/Render/RenderProjection.cpp
|
||||
Source/Render/RendererViewport.cpp
|
||||
Source/Render/RenderRay.cpp
|
||||
Source/Render/BitmapPixels.cpp
|
||||
Source/Render/Surface.cpp
|
||||
Source/Render/RenderQueues.cpp
|
||||
Source/Render/Texture.cpp
|
||||
Source/Render/UIRPData.cpp
|
||||
Source/Render/SurfaceDX9.cpp
|
||||
Source/Render/SurfaceDX7.cpp
|
||||
Source/Render/D3DX9Runtime.cpp
|
||||
Source/Render/TextureDX9.cpp
|
||||
Source/Render/TextureDX7.cpp
|
||||
Source/Render/TextureBindingDX7.cpp
|
||||
Source/Render/TextureAllocationDX7.cpp
|
||||
Source/Render/BitmapTextureCache.cpp
|
||||
Source/Render/SpriteAtlas.cpp
|
||||
Source/Render/DeviceContext.cpp
|
||||
Source/Render/DCBitmap.cpp
|
||||
Source/Render/DCSurface.cpp
|
||||
Source/Render/DeviceStateDX9.cpp
|
||||
Source/Render/DeviceOwnerDX9.cpp
|
||||
Source/Render/DeviceOwnerDX7.cpp
|
||||
Source/Render/DeviceCapabilitiesDX7.cpp
|
||||
Source/Render/TextureCalibrationDX7.cpp
|
||||
Source/Render/Primitives/RenderPrimitive.cpp
|
||||
Source/Render/Primitives/RenderPrimitivePool.cpp
|
||||
Source/Render/Primitives/RenderCommandPool.cpp
|
||||
Source/Render/Primitives/LightmappedPrimitive.cpp
|
||||
Source/Render/Primitives/DepthAlpha.cpp
|
||||
Source/Render/Primitives/RenderVertexPool.cpp
|
||||
Source/Render/Projection/RenderProjection.cpp
|
||||
Source/Render/Projection/RendererViewport.cpp
|
||||
Source/Render/Projection/RenderRay.cpp
|
||||
Source/Render/Textures/BitmapPixels.cpp
|
||||
Source/Render/Textures/Surface.cpp
|
||||
Source/Render/Primitives/RenderQueues.cpp
|
||||
Source/Render/Textures/Texture.cpp
|
||||
Source/Render/Primitives/UIRPData.cpp
|
||||
Source/Render/DX9/SurfaceDX9.cpp
|
||||
Source/Render/DX7/SurfaceDX7.cpp
|
||||
Source/Render/DX9/D3DX9Runtime.cpp
|
||||
Source/Render/DX9/TextureDX9.cpp
|
||||
Source/Render/DX7/TextureDX7.cpp
|
||||
Source/Render/DX7/TextureBindingDX7.cpp
|
||||
Source/Render/DX7/TextureAllocationDX7.cpp
|
||||
Source/Render/Textures/BitmapTextureCache.cpp
|
||||
Source/Render/Textures/SpriteAtlas.cpp
|
||||
Source/Render/DeviceContext/DeviceContext.cpp
|
||||
Source/Render/DeviceContext/DCBitmap.cpp
|
||||
Source/Render/DeviceContext/DCSurface.cpp
|
||||
Source/Render/DX9/DeviceStateDX9.cpp
|
||||
Source/Render/DX9/DeviceOwnerDX9.cpp
|
||||
Source/Render/DX7/DeviceOwnerDX7.cpp
|
||||
Source/Render/DX7/DeviceCapabilitiesDX7.cpp
|
||||
Source/Render/DX7/TextureCalibrationDX7.cpp
|
||||
Source/Render/RenderAdapter.cpp
|
||||
Source/Render/RenderAdapterDX7.cpp
|
||||
Source/Render/DX7/RenderAdapterDX7.cpp
|
||||
Source/Render/RenderBackends.cpp
|
||||
Source/Render/DisplayMode.cpp
|
||||
Source/Render/DisplayModeDX7.cpp
|
||||
Source/Render/DirectDrawEnumeration.cpp
|
||||
Source/Render/DeviceRecoveryDX9.cpp
|
||||
Source/Render/BackBufferDX9.cpp
|
||||
Source/Render/BackBufferDX7.cpp
|
||||
Source/Render/DX7/DisplayModeDX7.cpp
|
||||
Source/Render/DX7/DirectDrawEnumeration.cpp
|
||||
Source/Render/DX9/DeviceRecoveryDX9.cpp
|
||||
Source/Render/DX9/BackBufferDX9.cpp
|
||||
Source/Render/DX7/BackBufferDX7.cpp
|
||||
Source/Render/Direct3DErrors.cpp
|
||||
Source/Render/RendererBackBuffer.cpp
|
||||
Source/Render/DX9/RendererBackBuffer.cpp
|
||||
Source/Render/Renderer.cpp
|
||||
Source/Render/RendererDX9.cpp
|
||||
Source/Render/RenderSystemDX7.cpp
|
||||
Source/Render/RenderSystemDX9.cpp
|
||||
Source/Render/RendererDX9Operations.cpp
|
||||
Source/Render/RendererDX7Operations.cpp
|
||||
Source/Render/RenderToTextureDX7.cpp
|
||||
Source/Render/TextureModesDX9.cpp
|
||||
Source/Render/TextureModesDX7.cpp
|
||||
Source/Render/DX9/RendererDX9.cpp
|
||||
Source/Render/DX7/RenderSystemDX7.cpp
|
||||
Source/Render/DX9/RenderSystemDX9.cpp
|
||||
Source/Render/DX9/RendererDX9Operations.cpp
|
||||
Source/Render/DX7/RendererDX7Operations.cpp
|
||||
Source/Render/DX7/RenderToTextureDX7.cpp
|
||||
Source/Render/DX9/TextureModesDX9.cpp
|
||||
Source/Render/DX7/TextureModesDX7.cpp
|
||||
Source/Render/TextureStageModes.cpp
|
||||
Source/Render/RendererFogDX9.cpp
|
||||
Source/Render/RendererFogDX7.cpp
|
||||
Source/Render/OpaqueQueuesDX9.cpp
|
||||
Source/Render/GroundQueuesDX9.cpp
|
||||
Source/Render/AlphaQueuesDX9.cpp
|
||||
Source/Render/QueuedDrawingDX9.cpp
|
||||
Source/Render/RendererFrameDX9.cpp
|
||||
Source/Render/ScreenshotDX9.cpp
|
||||
Source/Render/ScreenshotDX7.cpp
|
||||
Source/Contents/Effect.cpp
|
||||
Source/Contents/EffectLists.cpp
|
||||
Source/Render/DX9/RendererFogDX9.cpp
|
||||
Source/Render/DX7/RendererFogDX7.cpp
|
||||
Source/Render/DX9/OpaqueQueuesDX9.cpp
|
||||
Source/Render/DX9/GroundQueuesDX9.cpp
|
||||
Source/Render/DX9/AlphaQueuesDX9.cpp
|
||||
Source/Render/DX9/QueuedDrawingDX9.cpp
|
||||
Source/Render/DX9/RendererFrameDX9.cpp
|
||||
Source/Render/DX9/ScreenshotDX9.cpp
|
||||
Source/Render/DX7/ScreenshotDX7.cpp
|
||||
Source/Contents/Effects/Effect.cpp
|
||||
Source/Contents/Effects/EffectLists.cpp
|
||||
Source/Render/BlendColor.cpp
|
||||
Source/Render/RendererPresentation.cpp
|
||||
Source/Render/RendererPresentationDX7.cpp
|
||||
Source/Render/FontCache.cpp
|
||||
Source/Render/TextContext.cpp
|
||||
Source/Render/DX9/RendererPresentation.cpp
|
||||
Source/Render/DX7/RendererPresentationDX7.cpp
|
||||
Source/Render/Text/FontCache.cpp
|
||||
Source/Render/Text/TextContext.cpp
|
||||
)
|
||||
target_include_directories(RagnarokRender PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/Source")
|
||||
target_compile_features(RagnarokRender PUBLIC cxx_std_20)
|
||||
|
|
@ -180,116 +181,116 @@ if(WIN32)
|
|||
target_link_libraries(RagnarokRender PUBLIC gdi32 winmm gdiplus d3d9 ddraw dxguid)
|
||||
|
||||
add_library(RagnarokUI STATIC
|
||||
Source/UI/WindowGeometry.cpp
|
||||
Source/UI/WindowCoordinates.cpp
|
||||
Source/UI/WindowAncestry.cpp
|
||||
Source/UI/WindowRegistration.cpp
|
||||
Source/UI/WindowRetirement.cpp
|
||||
Source/UI/WindowOrdering.cpp
|
||||
Source/UI/WindowMouseHit.cpp
|
||||
Source/UI/UIWindow.cpp
|
||||
Source/UI/UIControl.cpp
|
||||
Source/UI/UIDropDownBox.cpp
|
||||
Source/UI/ChatSuggestions.cpp
|
||||
Source/UI/ItemTagRetirement.cpp
|
||||
Source/UI/SnapRectangle.cpp
|
||||
Source/UI/SnapObject.cpp
|
||||
Source/UI/SnapMgr.cpp
|
||||
Source/UI/WindowSnapping.cpp
|
||||
Source/UI/FrameTextCache.cpp
|
||||
Source/UI/FrameFocus.cpp
|
||||
Source/UI/InputFocus.cpp
|
||||
Source/UI/UIFrameWnd.cpp
|
||||
Source/UI/ShortcutGrid.cpp
|
||||
Source/UI/WindowPolicy.cpp
|
||||
Source/UI/UIButton.cpp
|
||||
Source/UI/UIBasicButton.cpp
|
||||
Source/UI/UITextButton.cpp
|
||||
Source/UI/UINaviLinkButton.cpp
|
||||
Source/UI/UIEditCtrl.cpp
|
||||
Source/UI/UIEditVariants.cpp
|
||||
Source/UI/UIEditLinks.cpp
|
||||
Source/UI/UIBitmapButton.cpp
|
||||
Source/UI/UIBmpTextButton.cpp
|
||||
Source/UI/UIJobSlotButton.cpp
|
||||
Source/UI/UIPartyInfoWnd.cpp
|
||||
Source/UI/UIAdvenPartyBoardWnd.cpp
|
||||
Source/UI/UIApplyForPartyWnd.cpp
|
||||
Source/UI/UIRegisterPartyWnd.cpp
|
||||
Source/UI/UIRequestJoinPartyMgr.cpp
|
||||
Source/UI/UIRequestJoinPartyWnd.cpp
|
||||
Source/UI/UIChooseSellBuyWnd.cpp
|
||||
Source/UI/UIExchangeAcceptWnd.cpp
|
||||
Source/UI/UIJoinPartyAcceptWnd.cpp
|
||||
Source/Network/PartyJoinRequest.cpp
|
||||
Source/UI/UICheckBox.cpp
|
||||
Source/UI/UIScrollBar.cpp
|
||||
Source/UI/UIScrollBarNavi.cpp
|
||||
Source/UI/UIListBox.cpp
|
||||
Source/UI/UIListBoxEx.cpp
|
||||
Source/UI/UIComboBoxEx.cpp
|
||||
Source/UI/UIComboBoxDefWnd.cpp
|
||||
Source/UI/TextMarkup.cpp
|
||||
Source/UI/PixelTextWrapping.cpp
|
||||
Source/UI/ItemLinkDisplay.cpp
|
||||
Source/UI/UITextViewer.cpp
|
||||
Source/UI/UITextViewerLinks.cpp
|
||||
Source/UI/UITextViewerMessages.cpp
|
||||
Source/UI/Layout/WindowGeometry.cpp
|
||||
Source/UI/Layout/WindowCoordinates.cpp
|
||||
Source/UI/Window/WindowAncestry.cpp
|
||||
Source/UI/Window/WindowRegistration.cpp
|
||||
Source/UI/Window/WindowRetirement.cpp
|
||||
Source/UI/Window/WindowOrdering.cpp
|
||||
Source/UI/Window/WindowMouseHit.cpp
|
||||
Source/UI/Window/UIWindow.cpp
|
||||
Source/UI/Window/UIControl.cpp
|
||||
Source/UI/Lists/UIDropDownBox.cpp
|
||||
Source/UI/Chat/ChatSuggestions.cpp
|
||||
Source/UI/Edit/ItemTagRetirement.cpp
|
||||
Source/UI/Layout/SnapRectangle.cpp
|
||||
Source/UI/Layout/SnapObject.cpp
|
||||
Source/UI/Layout/SnapMgr.cpp
|
||||
Source/UI/Layout/WindowSnapping.cpp
|
||||
Source/UI/Window/FrameTextCache.cpp
|
||||
Source/UI/Window/FrameFocus.cpp
|
||||
Source/UI/Window/InputFocus.cpp
|
||||
Source/UI/Window/UIFrameWnd.cpp
|
||||
Source/UI/Shortcuts/ShortcutGrid.cpp
|
||||
Source/UI/Window/WindowPolicy.cpp
|
||||
Source/UI/Buttons/UIButton.cpp
|
||||
Source/UI/Buttons/UIBasicButton.cpp
|
||||
Source/UI/Buttons/UITextButton.cpp
|
||||
Source/UI/Buttons/UINaviLinkButton.cpp
|
||||
Source/UI/Edit/UIEditCtrl.cpp
|
||||
Source/UI/Edit/UIEditVariants.cpp
|
||||
Source/UI/Edit/UIEditLinks.cpp
|
||||
Source/UI/Buttons/UIBitmapButton.cpp
|
||||
Source/UI/Buttons/UIBmpTextButton.cpp
|
||||
Source/UI/Buttons/UIJobSlotButton.cpp
|
||||
Source/UI/Party/UIPartyInfoWnd.cpp
|
||||
Source/UI/Party/UIAdvenPartyBoardWnd.cpp
|
||||
Source/UI/Party/UIApplyForPartyWnd.cpp
|
||||
Source/UI/Party/UIRegisterPartyWnd.cpp
|
||||
Source/UI/Party/UIRequestJoinPartyMgr.cpp
|
||||
Source/UI/Party/UIRequestJoinPartyWnd.cpp
|
||||
Source/UI/Acceptance/UIChooseSellBuyWnd.cpp
|
||||
Source/UI/Acceptance/UIExchangeAcceptWnd.cpp
|
||||
Source/UI/Acceptance/UIJoinPartyAcceptWnd.cpp
|
||||
Source/Network/Packets/PartyJoinRequest.cpp
|
||||
Source/UI/Buttons/UICheckBox.cpp
|
||||
Source/UI/Lists/UIScrollBar.cpp
|
||||
Source/UI/Lists/UIScrollBarNavi.cpp
|
||||
Source/UI/Lists/UIListBox.cpp
|
||||
Source/UI/Lists/UIListBoxEx.cpp
|
||||
Source/UI/Lists/UIComboBoxEx.cpp
|
||||
Source/UI/Lists/UIComboBoxDefWnd.cpp
|
||||
Source/UI/Text/TextMarkup.cpp
|
||||
Source/UI/Text/PixelTextWrapping.cpp
|
||||
Source/UI/Text/ItemLinkDisplay.cpp
|
||||
Source/UI/Text/UITextViewer.cpp
|
||||
Source/UI/Text/UITextViewerLinks.cpp
|
||||
Source/UI/Text/UITextViewerMessages.cpp
|
||||
Source/UI/UIStaticBitmap.cpp
|
||||
Source/UI/UIStaticText.cpp
|
||||
Source/UI/UIMessageBox.cpp
|
||||
Source/UI/WindowDialogs.cpp
|
||||
Source/UI/Text/UIStaticText.cpp
|
||||
Source/UI/Window/UIMessageBox.cpp
|
||||
Source/UI/Window/WindowDialogs.cpp
|
||||
Source/Client/ReplayPacketRecorder.cpp
|
||||
Source/UI/CooldownState.cpp
|
||||
Source/UI/CooldownDrawing.cpp
|
||||
Source/UI/CooldownOwner.cpp
|
||||
Source/UI/ShortcutCooldowns.cpp
|
||||
Source/UI/ItemDrawing.cpp
|
||||
Source/UI/ShortcutPainting.cpp
|
||||
Source/UI/ShortcutBindings.cpp
|
||||
Source/UI/ShortcutLayout.cpp
|
||||
Source/UI/ShortcutActivation.cpp
|
||||
Source/UI/ShortcutControls.cpp
|
||||
Source/UI/ShortcutControlEvents.cpp
|
||||
Source/UI/ShortcutTooltip.cpp
|
||||
Source/UI/ShortcutPress.cpp
|
||||
Source/UI/ShortcutDrop.cpp
|
||||
Source/UI/ShortcutUse.cpp
|
||||
Source/UI/ShortcutVisibility.cpp
|
||||
Source/UI/ShortcutDetails.cpp
|
||||
Source/UI/SkillDetailClose.cpp
|
||||
Source/UI/NormalItemSlotLoad.cpp
|
||||
Source/UI/UIShortCutWnd.cpp
|
||||
Source/UI/TextWrapping.cpp
|
||||
Source/UI/ChatNotifications.cpp
|
||||
Source/UI/BrowserFactory.cpp
|
||||
Source/UI/BrowserPopupDispatch.cpp
|
||||
Source/UI/WindowFrameUpdate.cpp
|
||||
Source/UI/UIBalloonText.cpp
|
||||
Source/UI/UITransBalloonText.cpp
|
||||
Source/UI/ColoredText.cpp
|
||||
Source/UI/WindowBorder.cpp
|
||||
Source/UI/EditTextState.cpp
|
||||
Source/UI/EditViewport.cpp
|
||||
Source/UI/EditPainting.cpp
|
||||
Source/UI/PriceColor.cpp
|
||||
Source/UI/MerchantShopRefresh.cpp
|
||||
Source/UI/NavigationLink.cpp
|
||||
Source/UI/TextFitting.cpp
|
||||
Source/Client/ModeDragState.cpp
|
||||
Source/Client/ModeTooltip.cpp
|
||||
Source/Contents/CharacterConfigLoad.cpp
|
||||
Source/Contents/CharacterLinkedUserDataLoadAsyncWork.cpp
|
||||
Source/Contents/EmblemCache.cpp
|
||||
Source/Contents/EmblemUpload.cpp
|
||||
Source/Contents/ChangePartyMasterCompletion.cpp
|
||||
Source/Contents/PartyListCompletion.cpp
|
||||
Source/Contents/StopRecruitingCompletion.cpp
|
||||
Source/Contents/MyPartyCompletion.cpp
|
||||
Source/Contents/PartyRegistrationCompletion.cpp
|
||||
Source/Contents/PartyInfoCompletion.cpp
|
||||
Source/Contents/PartyJoinResult.cpp
|
||||
Source/Contents/PartyInvitation.cpp
|
||||
Source/UI/Cooldowns/CooldownState.cpp
|
||||
Source/UI/Cooldowns/CooldownDrawing.cpp
|
||||
Source/UI/Cooldowns/CooldownOwner.cpp
|
||||
Source/UI/Shortcuts/ShortcutCooldowns.cpp
|
||||
Source/UI/Shop/ItemDrawing.cpp
|
||||
Source/UI/Shortcuts/ShortcutPainting.cpp
|
||||
Source/UI/Shortcuts/ShortcutBindings.cpp
|
||||
Source/UI/Shortcuts/ShortcutLayout.cpp
|
||||
Source/UI/Shortcuts/ShortcutActivation.cpp
|
||||
Source/UI/Shortcuts/ShortcutControls.cpp
|
||||
Source/UI/Shortcuts/ShortcutControlEvents.cpp
|
||||
Source/UI/Shortcuts/ShortcutTooltip.cpp
|
||||
Source/UI/Shortcuts/ShortcutPress.cpp
|
||||
Source/UI/Shortcuts/ShortcutDrop.cpp
|
||||
Source/UI/Shortcuts/ShortcutUse.cpp
|
||||
Source/UI/Shortcuts/ShortcutVisibility.cpp
|
||||
Source/UI/Shortcuts/ShortcutDetails.cpp
|
||||
Source/UI/Shortcuts/SkillDetailClose.cpp
|
||||
Source/UI/Shortcuts/NormalItemSlotLoad.cpp
|
||||
Source/UI/Shortcuts/UIShortCutWnd.cpp
|
||||
Source/UI/Text/TextWrapping.cpp
|
||||
Source/UI/Chat/ChatNotifications.cpp
|
||||
Source/Client/Browser/BrowserFactory.cpp
|
||||
Source/Client/Browser/BrowserPopupDispatch.cpp
|
||||
Source/UI/Window/WindowFrameUpdate.cpp
|
||||
Source/UI/Text/UIBalloonText.cpp
|
||||
Source/UI/Text/UITransBalloonText.cpp
|
||||
Source/UI/Text/ColoredText.cpp
|
||||
Source/UI/Window/WindowBorder.cpp
|
||||
Source/UI/Edit/EditTextState.cpp
|
||||
Source/UI/Edit/EditViewport.cpp
|
||||
Source/UI/Edit/EditPainting.cpp
|
||||
Source/UI/Shop/PriceColor.cpp
|
||||
Source/UI/Shop/MerchantShopRefresh.cpp
|
||||
Source/UI/Text/NavigationLink.cpp
|
||||
Source/UI/Text/TextFitting.cpp
|
||||
Source/Client/Mode/ModeDragState.cpp
|
||||
Source/Client/Mode/ModeTooltip.cpp
|
||||
Source/Contents/UserData/CharacterConfigLoad.cpp
|
||||
Source/Contents/UserData/CharacterLinkedUserDataLoadAsyncWork.cpp
|
||||
Source/Contents/Emblems/EmblemCache.cpp
|
||||
Source/Contents/Emblems/EmblemUpload.cpp
|
||||
Source/Contents/Party/ChangePartyMasterCompletion.cpp
|
||||
Source/Contents/Party/PartyListCompletion.cpp
|
||||
Source/Contents/Party/StopRecruitingCompletion.cpp
|
||||
Source/Contents/Party/MyPartyCompletion.cpp
|
||||
Source/Contents/Party/PartyRegistrationCompletion.cpp
|
||||
Source/Contents/Party/PartyInfoCompletion.cpp
|
||||
Source/Contents/Party/PartyJoinResult.cpp
|
||||
Source/Contents/Party/PartyInvitation.cpp
|
||||
)
|
||||
target_include_directories(RagnarokUI PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/Source")
|
||||
target_compile_features(RagnarokUI PUBLIC cxx_std_20)
|
||||
|
|
@ -310,68 +311,68 @@ if(WIN32)
|
|||
|
||||
add_library(RagnarokResource STATIC
|
||||
Source/Resource/ResourceAliases.cpp
|
||||
Source/Resource/BitmapImage.cpp
|
||||
Source/Resource/BitmapImagePng.cpp
|
||||
Source/Resource/BitmapImageJpeg.cpp
|
||||
Source/Resource/IJL15Runtime.cpp
|
||||
Source/Resource/MilesRuntime.cpp
|
||||
Source/Resource/WaveResource.cpp
|
||||
Source/Resource/Bitmap/BitmapImage.cpp
|
||||
Source/Resource/Bitmap/BitmapImagePng.cpp
|
||||
Source/Resource/Bitmap/BitmapImageJpeg.cpp
|
||||
Source/Resource/Bitmap/IJL15Runtime.cpp
|
||||
Source/Resource/Audio/MilesRuntime.cpp
|
||||
Source/Resource/Audio/WaveResource.cpp
|
||||
Source/Resource/Resource.cpp
|
||||
Source/Resource/BitmapResource.cpp
|
||||
Source/Resource/SpriteResource.cpp
|
||||
Source/Resource/SpriteEncoding.cpp
|
||||
Source/Resource/ActionResource.cpp
|
||||
Source/Resource/TerrainResource.cpp
|
||||
Source/Resource/GroundResource.cpp
|
||||
Source/Resource/WorldResource.cpp
|
||||
Source/Resource/WorldEnvironment.cpp
|
||||
Source/Resource/WorldObjects.cpp
|
||||
Source/Resource/ModelMesh.cpp
|
||||
Source/Resource/ModelResource.cpp
|
||||
Source/Resource/ModelNodeLoading.cpp
|
||||
Source/Resource/ModelResourceV2.cpp
|
||||
Source/Resource/ModelNodeLoadingV2.cpp
|
||||
Source/Resource/AnimatedModelResource.cpp
|
||||
Source/Contents/ModelAnimation.cpp
|
||||
Source/Contents/ModelQuaternion.cpp
|
||||
Source/Contents/ModelNode.cpp
|
||||
Source/Contents/ModelTextureAnimation.cpp
|
||||
Source/Contents/ModelRendering.cpp
|
||||
Source/Contents/ModelTextureUV.cpp
|
||||
Source/Contents/ModelLighting.cpp
|
||||
Source/Contents/ModelNodeBounds.cpp
|
||||
Source/Contents/ModelActor.cpp
|
||||
Source/Contents/ModelActorBounds.cpp
|
||||
Source/Contents/ModelPlayback.cpp
|
||||
Source/Contents/ModelOcclusion.cpp
|
||||
Source/Contents/ModelMovies.cpp
|
||||
Source/Contents/WorldModelPlacement.cpp
|
||||
Source/Contents/WorldModelLoading.cpp
|
||||
Source/Contents/WorldGroundImport.cpp
|
||||
Source/Contents/WorldEnvironment.cpp
|
||||
Source/Contents/WorldSpatialTree.cpp
|
||||
Source/Contents/WorldSpatialInitialization.cpp
|
||||
Source/Contents/WorldRayQuery.cpp
|
||||
Source/Contents/WorldOcclusion.cpp
|
||||
Source/Contents/WorldModelView.cpp
|
||||
Source/Contents/WorldViewSpatial.cpp
|
||||
Source/Contents/CameraSmoothing.cpp
|
||||
Source/Contents/CameraShake.cpp
|
||||
Source/Contents/CameraFrame.cpp
|
||||
Source/Contents/CameraQueries.cpp
|
||||
Source/Contents/ModelSpatial.cpp
|
||||
Source/Contents/GroundSpatial.cpp
|
||||
Source/Contents/GroundGeometry.cpp
|
||||
Source/Contents/GroundLightmaps.cpp
|
||||
Source/Contents/GroundRendering.cpp
|
||||
Source/Contents/GroundPicking.cpp
|
||||
Source/Contents/GroundDecals.cpp
|
||||
Source/Contents/GroundWaterState.cpp
|
||||
Source/Contents/GroundWaterRendering.cpp
|
||||
Source/Contents/GroundLighting.cpp
|
||||
Source/Contents/GroundSamples.cpp
|
||||
Source/Contents/GroundLightingInitialization.cpp
|
||||
Source/Render/TextureCache.cpp
|
||||
Source/Resource/Bitmap/BitmapResource.cpp
|
||||
Source/Resource/Sprites/SpriteResource.cpp
|
||||
Source/Resource/Sprites/SpriteEncoding.cpp
|
||||
Source/Resource/Sprites/ActionResource.cpp
|
||||
Source/Resource/World/TerrainResource.cpp
|
||||
Source/Resource/World/GroundResource.cpp
|
||||
Source/Resource/World/WorldResource.cpp
|
||||
Source/Resource/World/WorldEnvironment.cpp
|
||||
Source/Resource/World/WorldObjects.cpp
|
||||
Source/Resource/Models/ModelMesh.cpp
|
||||
Source/Resource/Models/ModelResource.cpp
|
||||
Source/Resource/Models/ModelNodeLoading.cpp
|
||||
Source/Resource/Models/ModelResourceV2.cpp
|
||||
Source/Resource/Models/ModelNodeLoadingV2.cpp
|
||||
Source/Resource/Models/AnimatedModelResource.cpp
|
||||
Source/Contents/Models/ModelAnimation.cpp
|
||||
Source/Contents/Models/ModelQuaternion.cpp
|
||||
Source/Contents/Models/ModelNode.cpp
|
||||
Source/Contents/Models/ModelTextureAnimation.cpp
|
||||
Source/Contents/Models/ModelRendering.cpp
|
||||
Source/Contents/Models/ModelTextureUV.cpp
|
||||
Source/Contents/Models/ModelLighting.cpp
|
||||
Source/Contents/Models/ModelNodeBounds.cpp
|
||||
Source/Contents/Models/ModelActor.cpp
|
||||
Source/Contents/Models/ModelActorBounds.cpp
|
||||
Source/Contents/Models/ModelPlayback.cpp
|
||||
Source/Contents/Models/ModelOcclusion.cpp
|
||||
Source/Contents/Models/ModelMovies.cpp
|
||||
Source/Contents/World/WorldModelPlacement.cpp
|
||||
Source/Contents/World/WorldModelLoading.cpp
|
||||
Source/Contents/World/WorldGroundImport.cpp
|
||||
Source/Contents/World/WorldEnvironment.cpp
|
||||
Source/Contents/World/WorldSpatialTree.cpp
|
||||
Source/Contents/World/WorldSpatialInitialization.cpp
|
||||
Source/Contents/World/WorldRayQuery.cpp
|
||||
Source/Contents/World/WorldOcclusion.cpp
|
||||
Source/Contents/World/WorldModelView.cpp
|
||||
Source/Contents/World/WorldViewSpatial.cpp
|
||||
Source/Contents/Camera/CameraSmoothing.cpp
|
||||
Source/Contents/Camera/CameraShake.cpp
|
||||
Source/Contents/Camera/CameraFrame.cpp
|
||||
Source/Contents/Camera/CameraQueries.cpp
|
||||
Source/Contents/Models/ModelSpatial.cpp
|
||||
Source/Contents/Ground/GroundSpatial.cpp
|
||||
Source/Contents/Ground/GroundGeometry.cpp
|
||||
Source/Contents/Ground/GroundLightmaps.cpp
|
||||
Source/Contents/Ground/GroundRendering.cpp
|
||||
Source/Contents/Ground/GroundPicking.cpp
|
||||
Source/Contents/Ground/GroundDecals.cpp
|
||||
Source/Contents/Ground/GroundWaterState.cpp
|
||||
Source/Contents/Ground/GroundWaterRendering.cpp
|
||||
Source/Contents/Ground/GroundLighting.cpp
|
||||
Source/Contents/Ground/GroundSamples.cpp
|
||||
Source/Contents/Ground/GroundLightingInitialization.cpp
|
||||
Source/Render/Textures/TextureCache.cpp
|
||||
Source/Resource/EZeffectResource.cpp
|
||||
Source/Resource/ResourceMgr.cpp
|
||||
Source/Resource/ResourceFailures.cpp
|
||||
|
|
@ -379,9 +380,9 @@ if(WIN32)
|
|||
Source/Resource/TextureNames.cpp
|
||||
Source/Contents/SkinInfo.cpp
|
||||
Source/Resource/BinkRuntime.cpp
|
||||
Source/Contents/BinkMovie.cpp
|
||||
Source/Contents/BinkMovies.cpp
|
||||
Source/Render/ClientTextureSources.cpp
|
||||
Source/Contents/Movies/BinkMovie.cpp
|
||||
Source/Contents/Movies/BinkMovies.cpp
|
||||
Source/Render/Textures/ClientTextureSources.cpp
|
||||
)
|
||||
target_include_directories(RagnarokResource PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/Source")
|
||||
target_compile_features(RagnarokResource PUBLIC cxx_std_20)
|
||||
|
|
@ -390,15 +391,15 @@ if(WIN32)
|
|||
set_target_properties(RagnarokResource PROPERTIES CXX_EXTENSIONS OFF)
|
||||
|
||||
add_library(RagnarokNetwork STATIC
|
||||
Source/Network/CURLMgr.cpp
|
||||
Source/Network/CURLPostHander.cpp
|
||||
Source/Network/Http/CURLMgr.cpp
|
||||
Source/Network/Http/CURLPostHander.cpp
|
||||
Source/Network/TextEncoding.cpp
|
||||
Source/Network/ConnectionBuffer.cpp
|
||||
Source/Network/Connection.cpp
|
||||
Source/Network/PacketLengths.cpp
|
||||
Source/Network/ConnectionRuntime.cpp
|
||||
Source/Network/ShortcutPacket.cpp
|
||||
Source/Network/PartyJoinPacket.cpp
|
||||
Source/Network/Connection/ConnectionBuffer.cpp
|
||||
Source/Network/Connection/Connection.cpp
|
||||
Source/Network/Packets/PacketLengths.cpp
|
||||
Source/Network/Connection/ConnectionRuntime.cpp
|
||||
Source/Network/Packets/ShortcutPacket.cpp
|
||||
Source/Network/Packets/PartyJoinPacket.cpp
|
||||
)
|
||||
target_include_directories(RagnarokNetwork PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/Source")
|
||||
target_compile_features(RagnarokNetwork PUBLIC cxx_std_20)
|
||||
|
|
@ -406,104 +407,104 @@ if(WIN32)
|
|||
set_target_properties(RagnarokNetwork PROPERTIES CXX_EXTENSIONS OFF)
|
||||
|
||||
add_library(RagnarokContents STATIC
|
||||
Source/Contents/WhisperBlockMgr.cpp
|
||||
Source/Contents/Messenger/WhisperBlockMgr.cpp
|
||||
Source/Contents/CashEmotionMgr.cpp
|
||||
Source/Contents/AccountUserData.cpp
|
||||
Source/Contents/EmotionHotkeys.cpp
|
||||
Source/Contents/UserHotkeyScript.cpp
|
||||
Source/Contents/UserHotkeyMgr.cpp
|
||||
Source/Contents/AccountLinkedUserDataMgr.cpp
|
||||
Source/Contents/AccountService.cpp
|
||||
Source/Contents/ScriptOptions.cpp
|
||||
Source/Contents/GraphicsConfiguration.cpp
|
||||
Source/Contents/SoundConfiguration.cpp
|
||||
Source/Contents/SoundMgr.cpp
|
||||
Source/Contents/OptionWriter.cpp
|
||||
Source/Contents/UserData/AccountUserData.cpp
|
||||
Source/Contents/Hotkeys/EmotionHotkeys.cpp
|
||||
Source/Contents/Hotkeys/UserHotkeyScript.cpp
|
||||
Source/Contents/Hotkeys/UserHotkeyMgr.cpp
|
||||
Source/Contents/UserData/AccountLinkedUserDataMgr.cpp
|
||||
Source/Contents/UserData/AccountService.cpp
|
||||
Source/Contents/Configuration/ScriptOptions.cpp
|
||||
Source/Contents/Configuration/GraphicsConfiguration.cpp
|
||||
Source/Contents/Sound/SoundConfiguration.cpp
|
||||
Source/Contents/Sound/SoundMgr.cpp
|
||||
Source/Contents/Configuration/OptionWriter.cpp
|
||||
Source/Contents/MessageTable.cpp
|
||||
Source/Contents/AccountLinkedUserDataSaveAsyncWork.cpp
|
||||
Source/Contents/AccountLinkedUserDataLoadAsyncWork.cpp
|
||||
Source/Contents/CharacterLinkedUserDataMgr.cpp
|
||||
Source/Contents/CharacterLinkedUserDataSaveAsyncWork.cpp
|
||||
Source/Contents/CharacterConfigSave.cpp
|
||||
Source/Contents/SkillLevelConfig.cpp
|
||||
Source/Contents/SkillLevelRegistry.cpp
|
||||
Source/Contents/ServiceOptions.cpp
|
||||
Source/Contents/NormalItemSlots.cpp
|
||||
Source/Contents/SkillInfo.cpp
|
||||
Source/Contents/PlayerSkillBundle.cpp
|
||||
Source/Contents/SkillTreeScript.cpp
|
||||
Source/Contents/ClientSkills.cpp
|
||||
Source/Network/SkillUpdatePacket.cpp
|
||||
Source/Contents/ItemInfo.cpp
|
||||
Source/Contents/ItemDescription.cpp
|
||||
Source/Contents/ItemLink.cpp
|
||||
Source/Contents/UserData/AccountLinkedUserDataSaveAsyncWork.cpp
|
||||
Source/Contents/UserData/AccountLinkedUserDataLoadAsyncWork.cpp
|
||||
Source/Contents/UserData/CharacterLinkedUserDataMgr.cpp
|
||||
Source/Contents/UserData/CharacterLinkedUserDataSaveAsyncWork.cpp
|
||||
Source/Contents/UserData/CharacterConfigSave.cpp
|
||||
Source/Contents/Skills/SkillLevelConfig.cpp
|
||||
Source/Contents/Skills/SkillLevelRegistry.cpp
|
||||
Source/Contents/Configuration/ServiceOptions.cpp
|
||||
Source/Contents/UserData/NormalItemSlots.cpp
|
||||
Source/Contents/Skills/SkillInfo.cpp
|
||||
Source/Contents/Skills/PlayerSkillBundle.cpp
|
||||
Source/Contents/Skills/SkillTreeScript.cpp
|
||||
Source/Contents/Skills/ClientSkills.cpp
|
||||
Source/Network/Packets/SkillUpdatePacket.cpp
|
||||
Source/Contents/Items/ItemInfo.cpp
|
||||
Source/Contents/Items/ItemDescription.cpp
|
||||
Source/Contents/Items/ItemLink.cpp
|
||||
Source/Contents/TipBoxTitles.cpp
|
||||
Source/Contents/AutomaticSkills.cpp
|
||||
Source/Contents/AttackMotion.cpp
|
||||
Source/Client/ApplicationActivation.cpp
|
||||
Source/Client/ApplicationMessages.cpp
|
||||
Source/Client/BrowserInputHandoff.cpp
|
||||
Source/Client/WebBrowser.cpp
|
||||
Source/Client/BrowserRegistry.cpp
|
||||
Source/Client/WebEventReceiver.cpp
|
||||
Source/Client/BrowserMessages.cpp
|
||||
Source/Contents/HotkeyInfo.cpp
|
||||
Source/Contents/Skills/AutomaticSkills.cpp
|
||||
Source/Contents/Actors/AttackMotion.cpp
|
||||
Source/Client/Application/ApplicationActivation.cpp
|
||||
Source/Client/Application/ApplicationMessages.cpp
|
||||
Source/Client/Browser/BrowserInputHandoff.cpp
|
||||
Source/Client/Browser/WebBrowser.cpp
|
||||
Source/Client/Browser/BrowserRegistry.cpp
|
||||
Source/Client/Browser/WebEventReceiver.cpp
|
||||
Source/Client/Browser/BrowserMessages.cpp
|
||||
Source/Contents/Hotkeys/HotkeyInfo.cpp
|
||||
Source/Contents/PlayerNameDictionary.cpp
|
||||
Source/Contents/ItemNaming.cpp
|
||||
Source/Contents/ItemResources.cpp
|
||||
Source/Contents/StoreBackupData.cpp
|
||||
Source/Contents/MCStoreInfoBackup.cpp
|
||||
Source/Contents/MCStoreInfoBackupAsyncWork.cpp
|
||||
Source/Contents/EmblemDownload.cpp
|
||||
Source/Contents/EmblemDataDownloadAsyncWork.cpp
|
||||
Source/Contents/EmblemDataMgr.cpp
|
||||
Source/Contents/GuildEmblemReqBundle.cpp
|
||||
Source/Contents/EmblemDataUploadAsyncWork.cpp
|
||||
Source/Contents/AdvenPartyInfo.cpp
|
||||
Source/Contents/AdventurerAgencyMgr.cpp
|
||||
Source/Contents/ChangePartyMasterAsyncWork.cpp
|
||||
Source/Contents/LoadPartyListAsyncWork.cpp
|
||||
Source/Contents/StopRecruitingAsyncWork.cpp
|
||||
Source/Contents/LoadMyPartyAsyncWork.cpp
|
||||
Source/Contents/RegisterPartyAsyncWork.cpp
|
||||
Source/Contents/LoadPartyInfoAsyncWork.cpp
|
||||
Source/Contents/AsyncWorkRecycleObjectPoolMgr.cpp
|
||||
Source/Contents/AsyncWorkMgr.cpp
|
||||
Source/Contents/AgencyRequests.cpp
|
||||
Source/Contents/Items/ItemNaming.cpp
|
||||
Source/Contents/Items/ItemResources.cpp
|
||||
Source/Contents/Store/StoreBackupData.cpp
|
||||
Source/Contents/Store/MCStoreInfoBackup.cpp
|
||||
Source/Contents/Store/MCStoreInfoBackupAsyncWork.cpp
|
||||
Source/Contents/Emblems/EmblemDownload.cpp
|
||||
Source/Contents/Emblems/EmblemDataDownloadAsyncWork.cpp
|
||||
Source/Contents/Emblems/EmblemDataMgr.cpp
|
||||
Source/Contents/Emblems/GuildEmblemReqBundle.cpp
|
||||
Source/Contents/Emblems/EmblemDataUploadAsyncWork.cpp
|
||||
Source/Contents/Party/AdvenPartyInfo.cpp
|
||||
Source/Contents/Party/AdventurerAgencyMgr.cpp
|
||||
Source/Contents/Party/ChangePartyMasterAsyncWork.cpp
|
||||
Source/Contents/Party/LoadPartyListAsyncWork.cpp
|
||||
Source/Contents/Party/StopRecruitingAsyncWork.cpp
|
||||
Source/Contents/Party/LoadMyPartyAsyncWork.cpp
|
||||
Source/Contents/Party/RegisterPartyAsyncWork.cpp
|
||||
Source/Contents/Party/LoadPartyInfoAsyncWork.cpp
|
||||
Source/Contents/Async/AsyncWorkRecycleObjectPoolMgr.cpp
|
||||
Source/Contents/Async/AsyncWorkMgr.cpp
|
||||
Source/Contents/Party/AgencyRequests.cpp
|
||||
Source/Contents/ForbiddenWords.cpp
|
||||
Source/Contents/JobNames.cpp
|
||||
Source/Contents/SpriteDrawingPolicy.cpp
|
||||
Source/Contents/JobInheritance.cpp
|
||||
Source/Contents/MessengerMember.cpp
|
||||
Source/Contents/ClientMessenger.cpp
|
||||
Source/Contents/RenderObjectState.cpp
|
||||
Source/Contents/GameObject.cpp
|
||||
Source/Contents/RenderObject.cpp
|
||||
Source/Contents/WorldObjects.cpp
|
||||
Source/Contents/WorldActors.cpp
|
||||
Source/Contents/EffectAttachments.cpp
|
||||
Source/Contents/EffectTypes.cpp
|
||||
Source/Contents/RagEffectState.cpp
|
||||
Source/Contents/RagEffectInitialization.cpp
|
||||
Source/Contents/RagEffectResourceSelection.cpp
|
||||
Source/Contents/EffectPrimitiveState.cpp
|
||||
Source/Contents/EffectPrimitiveColor.cpp
|
||||
Source/Contents/EffectPrimitiveMotion.cpp
|
||||
Source/Contents/EffectPrimitiveRendering.cpp
|
||||
Source/Contents/EffectPrimitiveRecords.cpp
|
||||
Source/Contents/EffectParticle.cpp
|
||||
Source/Contents/PartyEffect.cpp
|
||||
Source/Contents/EffectActor.cpp
|
||||
Source/Contents/AttachedEffect.cpp
|
||||
Source/Contents/PartyMemberEffects.cpp
|
||||
Source/Contents/EffectVisibility.cpp
|
||||
Source/Contents/TerrainHeight.cpp
|
||||
Source/Contents/TerrainCoordinates.cpp
|
||||
Source/Contents/TerrainPicking.cpp
|
||||
Source/Contents/TerrainPlane.cpp
|
||||
Source/Contents/WorldTerrainPicking.cpp
|
||||
Source/Contents/WorldProximity.cpp
|
||||
Source/Contents/JobNameInitialization.cpp
|
||||
Source/Contents/Jobs/JobNames.cpp
|
||||
Source/Contents/Actors/SpriteDrawingPolicy.cpp
|
||||
Source/Contents/Jobs/JobInheritance.cpp
|
||||
Source/Contents/Messenger/MessengerMember.cpp
|
||||
Source/Contents/Messenger/ClientMessenger.cpp
|
||||
Source/Contents/Actors/RenderObjectState.cpp
|
||||
Source/Contents/Actors/GameObject.cpp
|
||||
Source/Contents/Actors/RenderObject.cpp
|
||||
Source/Contents/World/WorldObjects.cpp
|
||||
Source/Contents/World/WorldActors.cpp
|
||||
Source/Contents/Effects/EffectAttachments.cpp
|
||||
Source/Contents/Effects/EffectTypes.cpp
|
||||
Source/Contents/Effects/RagEffectState.cpp
|
||||
Source/Contents/Effects/RagEffectInitialization.cpp
|
||||
Source/Contents/Effects/RagEffectResourceSelection.cpp
|
||||
Source/Contents/Effects/EffectPrimitiveState.cpp
|
||||
Source/Contents/Effects/EffectPrimitiveColor.cpp
|
||||
Source/Contents/Effects/EffectPrimitiveMotion.cpp
|
||||
Source/Contents/Effects/EffectPrimitiveRendering.cpp
|
||||
Source/Contents/Effects/EffectPrimitiveRecords.cpp
|
||||
Source/Contents/Effects/EffectParticle.cpp
|
||||
Source/Contents/Effects/PartyEffect.cpp
|
||||
Source/Contents/Effects/EffectActor.cpp
|
||||
Source/Contents/Effects/AttachedEffect.cpp
|
||||
Source/Contents/Effects/PartyMemberEffects.cpp
|
||||
Source/Contents/Effects/EffectVisibility.cpp
|
||||
Source/Contents/Ground/TerrainHeight.cpp
|
||||
Source/Contents/Ground/TerrainCoordinates.cpp
|
||||
Source/Contents/Ground/TerrainPicking.cpp
|
||||
Source/Contents/Ground/TerrainPlane.cpp
|
||||
Source/Contents/World/WorldTerrainPicking.cpp
|
||||
Source/Contents/World/WorldProximity.cpp
|
||||
Source/Contents/Jobs/JobNameInitialization.cpp
|
||||
Source/Contents/ShowRankingScheduler.cpp
|
||||
)
|
||||
target_include_directories(RagnarokContents PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/Source")
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ static void BuildFullKeyName(const char* keyname, char* buffer) {
|
|||
changes. Include the real prerequisite interfaces, implementations and affected callers, or land them first.
|
||||
- Preserve functions that already match. Fix compile errors and structural differences; byte identity is a
|
||||
bonus, not permission to distort source or spend unbounded time tuning it.
|
||||
- Do not add WoW `// VERIFY:` hashes or use `re/tools/verify.py`; neither is this project's verification workflow.
|
||||
- Do not add game `// VERIFY:` hashes or use `re/tools/verify.py`; neither is this project's verification workflow.
|
||||
- Claims, submission scope and peer-review procedure follow `AGENTS.md` and current server guidance.
|
||||
|
||||
## 2b. Cast chains mean the types are wrong
|
||||
|
|
@ -152,7 +152,7 @@ class CResourceCache {
|
|||
|
||||
- Reuse the appropriate header under `Source/` for shared enums and data types.
|
||||
- Use an existing `Types.h` if the subsystem has one; do not create a repository-wide `Types.h` migration.
|
||||
- Keep dependencies small and avoid cycles. Do not introduce WoW-specific DB or event headers.
|
||||
- Keep dependencies small and avoid cycles. Do not introduce game-specific DB or event headers.
|
||||
|
||||
## 6. Diagnostic file and line arguments preserve original behavior
|
||||
|
||||
|
|
@ -166,6 +166,25 @@ the original instructions.
|
|||
- This target is Windows x86. Keep code in its assigned existing translation unit and subsystem headers.
|
||||
- Use the original Win32, DirectDraw, Direct3D, Lua and codec ABIs where evidenced. Preserve calling
|
||||
conventions, ownership, field widths and failure behavior.
|
||||
- Do not introduce WoW architecture macros, parallel `Win32/` / `Win64/` trees or a new portability layer.
|
||||
- Compile individual units with the configured Clank toolchain and `compile.json`, not a new build system.
|
||||
- Missing original instructions are a blocker, not permission to invent a fallback or partial implementation.
|
||||
|
||||
## 8. Reconstruct source, not instructions
|
||||
|
||||
- Prefer the original programmer's types and algorithms over instruction-shaped C++. Byte identity is a bonus,
|
||||
never a reason for cryptic code. Use compiler intrinsics only with clear evidence that the original source
|
||||
used them; an optimized SIMD instruction alone is not evidence. Scalar data is not `__m128i`.
|
||||
- Recover records and members instead of dereferencing integer pointers cast onto byte buffers. At a real
|
||||
binary-format boundary, use a typed record or `memcpy` for unaligned fields; preserve layout and aliasing.
|
||||
- Apply namespace and API conventions consistently throughout a subsystem, including declarations and callers.
|
||||
- Group cohesive implementations and their headers in subsystem folders, e.g. `Client/Browser/`. Group by
|
||||
actual ownership and dependencies, not a loose keyword; update includes and build metadata with every move.
|
||||
- Use SDK/library constants and identifiers directly: `WS_CHILD | WS_VISIBLE`, `CGID_DocHostCommandHandler`.
|
||||
Do not duplicate documented definitions. Name game-specific choices with an enum, or `constexpr` when an enum
|
||||
is unsuitable; do not turn serialized data, hashes or lookup tables into invented symbolic constants.
|
||||
- Do not include `<mmsystem.h>`; include the specific Windows API headers actually required. Formatter-control
|
||||
comments are forbidden too. Preserve include dependencies without `clang-format` suppression comments.
|
||||
- Separate different logical phases with a blank line; keep related assignments together. Use a 160-column
|
||||
limit, rather than wrapping short calls into instruction-like fragments. Formatting must not change behavior.
|
||||
- Leave exactly one blank line after an include block before declarations, including in headers. Never keep
|
||||
more than one consecutive blank line; whitespace-only lines count as blank.
|
||||
|
|
|
|||
|
|
@ -3,5 +3,5 @@
|
|||
This tree is coordinated with Clank Together. Functions and data carry stable symbol IDs
|
||||
instead of addresses (`// FUNCTION: fn_01234`, `// GLOBAL: gl_00042`); the coordinator's symbol database holds
|
||||
their addresses in every client build, so a new client version needs new addresses, not a retagged tree.
|
||||
`decomp.json` and `config/compile.json` pin the VS compiler and the exact command line of every source.
|
||||
`decomp.json` and `compile.json` pin the VS compiler and the exact command line of every source.
|
||||
See `AGENTS.md` for how to contribute.
|
||||
|
|
|
|||
|
|
@ -4,11 +4,9 @@
|
|||
#include <algorithm>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <emmintrin.h>
|
||||
#include <zlib.h>
|
||||
|
||||
namespace {
|
||||
|
||||
std::uint32_t Read32(const std::uint8_t* bytes) {
|
||||
std::uint32_t value;
|
||||
std::memcpy(&value, bytes, sizeof(value));
|
||||
|
|
@ -29,22 +27,18 @@ namespace {
|
|||
// FUNCTION: fn_05116
|
||||
std::uint64_t ReadAuxiliaryIdentifier(const void* data, std::size_t size) {
|
||||
if (size != 0) {
|
||||
const __m128i header = _mm_loadu_si128(static_cast<const __m128i*>(data));
|
||||
if (static_cast<std::uint8_t>(_mm_cvtsi128_si32(header)) <= 1) {
|
||||
std::uint64_t identifier;
|
||||
_mm_storel_epi64(reinterpret_cast<__m128i*>(&identifier), _mm_srli_si128(header, 4));
|
||||
return identifier;
|
||||
const auto* header = static_cast<const std::uint8_t*>(data);
|
||||
if (header[0] <= 1) {
|
||||
return Read64(header + 4);
|
||||
}
|
||||
}
|
||||
|
||||
return UINT64_MAX;
|
||||
}
|
||||
|
||||
void SortEntries(std::vector<myGPack::PakEntry>& entries) {
|
||||
std::sort(entries.begin(), entries.end(), [](const auto& first, const auto& second) {
|
||||
return first.name < second.name;
|
||||
});
|
||||
std::sort(entries.begin(), entries.end(), [](const auto& first, const auto& second) { return first.name < second.name; });
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// OFFSET: 0x00E555A0
|
||||
|
|
@ -80,6 +74,7 @@ bool CGPak::Open(CPakFile* file) {
|
|||
if (!file) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this->m_file = file;
|
||||
const std::uint8_t* header = file->Read(0, 46);
|
||||
if (std::memcmp(header, "Event Horizon", 14) == 0) {
|
||||
|
|
@ -95,6 +90,7 @@ bool CGPak::Open(CPakFile* file) {
|
|||
}
|
||||
|
||||
bool loaded;
|
||||
|
||||
switch (this->m_version & 0xFF00) {
|
||||
case 0x100:
|
||||
loaded = this->ReadTableV1();
|
||||
|
|
@ -109,9 +105,11 @@ bool CGPak::Open(CPakFile* file) {
|
|||
loaded = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if (loaded) {
|
||||
return true;
|
||||
}
|
||||
|
||||
this->Reset();
|
||||
return false;
|
||||
}
|
||||
|
|
@ -119,20 +117,22 @@ bool CGPak::Open(CPakFile* file) {
|
|||
// OFFSET: 0x00AEC050
|
||||
// FUNCTION: fn_18133
|
||||
bool CGPak::ReadTableV1() {
|
||||
this->m_tableSize =
|
||||
static_cast<std::uint32_t>(this->m_file->GetSize()) - static_cast<std::uint32_t>(this->m_tableOffset);
|
||||
this->m_tableSize = static_cast<std::uint32_t>(this->m_file->GetSize()) - static_cast<std::uint32_t>(this->m_tableOffset);
|
||||
const std::uint8_t* cursor = this->m_file->Read(this->m_tableOffset, this->m_tableSize);
|
||||
this->m_entries.resize(this->m_entryCount);
|
||||
|
||||
std::uint32_t maximum = 0;
|
||||
std::uint32_t sequence = 1;
|
||||
std::int32_t legacyKey = 95001;
|
||||
|
||||
for (std::uint32_t i = 0; i < this->m_entryCount; ++i) {
|
||||
std::uint32_t nameSize = Read32(cursor);
|
||||
cursor += 4;
|
||||
char name[256];
|
||||
|
||||
if (this->m_version < 0x101) {
|
||||
std::int32_t length = static_cast<std::int32_t>(std::strlen(reinterpret_cast<const char*>(cursor)) + 1);
|
||||
|
||||
for (std::int32_t j = 0; j < length; ++j) {
|
||||
name[j] = static_cast<char>(SwapNibbles(cursor[j]));
|
||||
}
|
||||
|
|
@ -140,18 +140,23 @@ bool CGPak::ReadTableV1() {
|
|||
if (this->m_version > 0x103) {
|
||||
return false;
|
||||
}
|
||||
|
||||
cursor += 2;
|
||||
std::int32_t length = static_cast<std::int32_t>(nameSize - 6);
|
||||
|
||||
for (std::int32_t j = 0; j < length; ++j) {
|
||||
name[j] = static_cast<char>(SwapNibbles(cursor[j]));
|
||||
}
|
||||
|
||||
std::int32_t number = legacyKey;
|
||||
if (this->m_version != 0x101) {
|
||||
number = static_cast<std::int32_t>(3 * (31669u - (sequence >> 1)));
|
||||
}
|
||||
|
||||
if (number < 10000) {
|
||||
number += 85000;
|
||||
}
|
||||
|
||||
char digits[20];
|
||||
_itoa(number, digits, 10);
|
||||
std::uint8_t key[8];
|
||||
|
|
@ -178,13 +183,14 @@ bool CGPak::ReadTableV1() {
|
|||
entry.name.Assign(name);
|
||||
|
||||
const char* extension = std::strrchr(name, '.');
|
||||
bool special = extension && (_stricmp(extension, ".gnd") == 0 || _stricmp(extension, ".gat") == 0 ||
|
||||
_stricmp(extension, ".act") == 0 || _stricmp(extension, ".str") == 0);
|
||||
bool special = extension && (_stricmp(extension, ".gnd") == 0 || _stricmp(extension, ".gat") == 0 || _stricmp(extension, ".act") == 0 ||
|
||||
_stricmp(extension, ".str") == 0);
|
||||
entry.flags |= special ? 4 : 2;
|
||||
maximum = std::max(maximum, entry.alignedSize);
|
||||
sequence += 5;
|
||||
legacyKey -= 2;
|
||||
}
|
||||
|
||||
SortEntries(this->m_entries);
|
||||
this->m_scratch.resize(maximum);
|
||||
return true;
|
||||
|
|
@ -200,6 +206,7 @@ bool CGPak::ReadTableV2() {
|
|||
const std::uint8_t* source = this->m_file->Read(this->m_tableOffset + 8, compressed);
|
||||
uLongf length = original + 8;
|
||||
std::vector<std::uint8_t> decoded(length);
|
||||
|
||||
if (uncompress(decoded.data(), &length, source, compressed) != Z_OK) {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -207,6 +214,7 @@ bool CGPak::ReadTableV2() {
|
|||
this->m_entries.resize(this->m_entryCount);
|
||||
const std::uint8_t* cursor = decoded.data();
|
||||
std::uint32_t maximum = 0;
|
||||
|
||||
for (std::uint32_t i = 0; i < this->m_entryCount; ++i) {
|
||||
const char* name = reinterpret_cast<const char*>(cursor);
|
||||
const std::uint8_t* metadata = cursor + std::strlen(name) + 1;
|
||||
|
|
@ -220,6 +228,7 @@ bool CGPak::ReadTableV2() {
|
|||
entry.name.Assign(name);
|
||||
maximum = std::max(maximum, entry.alignedSize);
|
||||
}
|
||||
|
||||
SortEntries(this->m_entries);
|
||||
this->m_scratch.resize(maximum);
|
||||
return true;
|
||||
|
|
@ -236,6 +245,7 @@ bool CGPak::ReadTableV3() {
|
|||
const std::uint8_t* source = this->m_file->Read(this->m_tableOffset + 12, compressed);
|
||||
uLongf length = original + 8;
|
||||
std::vector<std::uint8_t> decoded(length);
|
||||
|
||||
if (uncompress(decoded.data(), &length, source, compressed) != Z_OK) {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -243,6 +253,7 @@ bool CGPak::ReadTableV3() {
|
|||
this->m_entries.resize(this->m_entryCount);
|
||||
const std::uint8_t* cursor = decoded.data();
|
||||
std::uint32_t maximum = 0;
|
||||
|
||||
for (std::uint32_t i = 0; i < this->m_entryCount; ++i) {
|
||||
const char* name = reinterpret_cast<const char*>(cursor);
|
||||
const std::uint8_t* metadata = cursor + std::strlen(name) + 1;
|
||||
|
|
@ -252,12 +263,11 @@ bool CGPak::ReadTableV3() {
|
|||
entry.alignedSize = Read32(metadata + 4);
|
||||
entry.originalSize = Read32(metadata + 8);
|
||||
entry.flags = metadata[12];
|
||||
const std::uint32_t offsetLow = Read32(metadata + 13);
|
||||
reinterpret_cast<std::uint32_t*>(&entry.dataOffset)[1] = Read32(metadata + 17);
|
||||
reinterpret_cast<std::uint32_t*>(&entry.dataOffset)[0] = offsetLow;
|
||||
entry.dataOffset = Read64(metadata + 13);
|
||||
entry.name.Assign(name);
|
||||
maximum = std::max(maximum, entry.alignedSize);
|
||||
}
|
||||
|
||||
SortEntries(this->m_entries);
|
||||
this->m_scratch.resize(maximum);
|
||||
return true;
|
||||
|
|
@ -266,16 +276,17 @@ bool CGPak::ReadTableV3() {
|
|||
// OFFSET: 0x00AEBA30
|
||||
// FUNCTION: fn_18128
|
||||
bool CGPak::Find(const myGPack::PakName& name, myGPack::PakEntry* entry) const {
|
||||
auto found = std::lower_bound(
|
||||
this->m_entries.begin(), this->m_entries.end(), name,
|
||||
[](const myGPack::PakEntry& candidate, const myGPack::PakName& key) { return candidate.name < key; }
|
||||
);
|
||||
auto found = std::lower_bound(this->m_entries.begin(), this->m_entries.end(), name, [](const myGPack::PakEntry& candidate, const myGPack::PakName& key) {
|
||||
return candidate.name < key;
|
||||
});
|
||||
if (found == this->m_entries.end() || found->name != name) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (entry) {
|
||||
std::memcpy(entry, &*found, sizeof(*entry));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -290,6 +301,7 @@ void CGPak::ReadAuxiliary(std::vector<std::uint8_t>& output, std::uint64_t* iden
|
|||
|
||||
std::uint32_t size;
|
||||
std::uint64_t offset;
|
||||
|
||||
switch (this->m_version & 0xFF00) {
|
||||
case 0x200:
|
||||
if (this->m_version < 0x201) {
|
||||
|
|
|
|||
|
|
@ -1,14 +1,10 @@
|
|||
#include "Archive/MemMapPakFile.h"
|
||||
|
||||
#include <bit>
|
||||
|
||||
// OFFSET: 0x00AE99D0
|
||||
// FUNCTION: fn_18111
|
||||
// OFFSET: 0x00AECAA0
|
||||
// FUNCTION: fn_18140
|
||||
CMemMapPakFile::CMemMapPakFile()
|
||||
: m_handle(nullptr), m_mapping(nullptr), m_viewSize(0), m_windowSize(0x20000000), m_size(0), m_viewOffset(0),
|
||||
m_view(nullptr) {
|
||||
CMemMapPakFile::CMemMapPakFile() : m_handle(nullptr), m_mapping(nullptr), m_viewSize(0), m_windowSize(0x20000000), m_size(0), m_viewOffset(0), m_view(nullptr) {
|
||||
SYSTEM_INFO information;
|
||||
GetSystemInfo(&information);
|
||||
this->m_offsetMask = 0xFFFFFFFF00000000ULL | static_cast<std::uint32_t>(~(information.dwAllocationGranularity - 1));
|
||||
|
|
@ -30,8 +26,7 @@ std::uint64_t CMemMapPakFile::GetSize() const {
|
|||
// OFFSET: 0x00AECB10
|
||||
// FUNCTION: fn_18141
|
||||
bool CMemMapPakFile::Open(const char* filename) {
|
||||
this->m_handle =
|
||||
CreateFileA(filename, GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
|
||||
this->m_handle = CreateFileA(filename, GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
|
||||
if (this->m_handle == INVALID_HANDLE_VALUE) {
|
||||
this->m_handle = nullptr;
|
||||
return false;
|
||||
|
|
@ -39,13 +34,15 @@ bool CMemMapPakFile::Open(const char* filename) {
|
|||
|
||||
LARGE_INTEGER size;
|
||||
GetFileSizeEx(this->m_handle, &size);
|
||||
this->m_size = std::bit_cast<std::uint64_t>(size.QuadPart);
|
||||
this->m_size = static_cast<std::uint64_t>(size.QuadPart);
|
||||
this->m_viewOffset = 0;
|
||||
this->m_viewSize = 0;
|
||||
this->m_mapping = CreateFileMappingA(this->m_handle, nullptr, PAGE_READONLY, 0, 0, nullptr);
|
||||
|
||||
if (this->m_mapping) {
|
||||
return true;
|
||||
}
|
||||
|
||||
this->m_windowSize = 0;
|
||||
return false;
|
||||
}
|
||||
|
|
@ -57,10 +54,12 @@ void CMemMapPakFile::Close() {
|
|||
UnmapViewOfFile(this->m_view);
|
||||
this->m_view = nullptr;
|
||||
}
|
||||
|
||||
if (this->m_mapping) {
|
||||
CloseHandle(this->m_mapping);
|
||||
this->m_mapping = nullptr;
|
||||
}
|
||||
|
||||
if (this->m_handle) {
|
||||
CloseHandle(this->m_handle);
|
||||
this->m_handle = nullptr;
|
||||
|
|
@ -74,27 +73,29 @@ std::uint8_t* CMemMapPakFile::Read(std::uint64_t offset, std::uint32_t length) {
|
|||
if (offset >= this->m_viewOffset && offset + length <= this->m_viewOffset + this->m_viewSize) {
|
||||
return this->m_view + static_cast<std::uint32_t>(offset - this->m_viewOffset);
|
||||
}
|
||||
|
||||
if (this->m_view) {
|
||||
UnmapViewOfFile(this->m_view);
|
||||
this->m_view = nullptr;
|
||||
}
|
||||
|
||||
while (this->m_windowSize >=
|
||||
length + (static_cast<std::uint32_t>(offset) & ~static_cast<std::uint32_t>(this->m_offsetMask))) {
|
||||
while (this->m_windowSize >= length + (static_cast<std::uint32_t>(offset) & ~static_cast<std::uint32_t>(this->m_offsetMask))) {
|
||||
this->m_viewOffset = offset & this->m_offsetMask;
|
||||
this->m_viewSize = this->m_windowSize;
|
||||
SIZE_T bytes = this->m_windowSize;
|
||||
|
||||
if (this->m_viewOffset + this->m_windowSize > this->m_size) {
|
||||
bytes = 0;
|
||||
this->m_viewSize = static_cast<std::uint32_t>(this->m_size - this->m_viewOffset);
|
||||
}
|
||||
this->m_view = static_cast<std::uint8_t*>(MapViewOfFile(
|
||||
this->m_mapping, FILE_MAP_READ, static_cast<DWORD>(this->m_viewOffset >> 32),
|
||||
static_cast<DWORD>(this->m_viewOffset), bytes
|
||||
));
|
||||
|
||||
this->m_view = static_cast<std::uint8_t*>(
|
||||
MapViewOfFile(this->m_mapping, FILE_MAP_READ, static_cast<DWORD>(this->m_viewOffset >> 32), static_cast<DWORD>(this->m_viewOffset), bytes)
|
||||
);
|
||||
if (this->m_view) {
|
||||
return this->m_view + static_cast<std::uint32_t>(offset - this->m_viewOffset);
|
||||
}
|
||||
|
||||
this->m_windowSize >>= 1;
|
||||
if (!this->m_windowSize) {
|
||||
break;
|
||||
|
|
@ -113,14 +114,16 @@ std::uint8_t* CMemMapPakFile::Read(std::uint64_t offset, std::uint32_t length) {
|
|||
this->m_buffer.resize(length);
|
||||
this->m_view = this->m_buffer.data();
|
||||
}
|
||||
|
||||
LARGE_INTEGER position;
|
||||
position.QuadPart = std::bit_cast<std::int64_t>(offset);
|
||||
position.QuadPart = static_cast<std::int64_t>(offset);
|
||||
SetFilePointerEx(this->m_handle, position, nullptr, FILE_BEGIN);
|
||||
DWORD read = 0;
|
||||
|
||||
if (ReadFile(this->m_handle, this->m_buffer.data(), length, &read, nullptr)) {
|
||||
// The original accepts a successful short read; it does not compare read.
|
||||
this->m_view = this->m_buffer.empty() ? nullptr : this->m_buffer.data();
|
||||
return this->m_view;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@
|
|||
|
||||
#include "Archive/PakFile.h"
|
||||
|
||||
// Class name established by original RTTI; field/method names reconstructed.
|
||||
class CMemMapPakFile : public CPakFile {
|
||||
public:
|
||||
CMemMapPakFile();
|
||||
|
|
|
|||
|
|
@ -5,21 +5,18 @@
|
|||
|
||||
namespace myGPack {
|
||||
namespace {
|
||||
|
||||
// STATIC: 0x01159EC8
|
||||
// GLOBAL: gl_13428
|
||||
constexpr std::uint8_t s_initialPermutation[64] = {
|
||||
58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4, 62, 54, 46, 38, 30, 22,
|
||||
14, 6, 64, 56, 48, 40, 32, 24, 16, 8, 57, 49, 41, 33, 25, 17, 9, 1, 59, 51, 43, 35,
|
||||
27, 19, 11, 3, 61, 53, 45, 37, 29, 21, 13, 5, 63, 55, 47, 39, 31, 23, 15, 7,
|
||||
58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4, 62, 54, 46, 38, 30, 22, 14, 6, 64, 56, 48, 40, 32, 24, 16, 8,
|
||||
57, 49, 41, 33, 25, 17, 9, 1, 59, 51, 43, 35, 27, 19, 11, 3, 61, 53, 45, 37, 29, 21, 13, 5, 63, 55, 47, 39, 31, 23, 15, 7,
|
||||
};
|
||||
|
||||
// STATIC: 0x01159F08
|
||||
// GLOBAL: gl_13429
|
||||
constexpr std::uint8_t s_finalPermutation[64] = {
|
||||
40, 8, 48, 16, 56, 24, 64, 32, 39, 7, 47, 15, 55, 23, 63, 31, 38, 6, 46, 14, 54, 22,
|
||||
62, 30, 37, 5, 45, 13, 53, 21, 61, 29, 36, 4, 44, 12, 52, 20, 60, 28, 35, 3, 43, 11,
|
||||
51, 19, 59, 27, 34, 2, 42, 10, 50, 18, 58, 26, 33, 1, 41, 9, 49, 17, 57, 25,
|
||||
40, 8, 48, 16, 56, 24, 64, 32, 39, 7, 47, 15, 55, 23, 63, 31, 38, 6, 46, 14, 54, 22, 62, 30, 37, 5, 45, 13, 53, 21, 61, 29,
|
||||
36, 4, 44, 12, 52, 20, 60, 28, 35, 3, 43, 11, 51, 19, 59, 27, 34, 2, 42, 10, 50, 18, 58, 26, 33, 1, 41, 9, 49, 17, 57, 25,
|
||||
};
|
||||
|
||||
// STATIC: 0x01159FC0
|
||||
|
|
@ -32,42 +29,38 @@ namespace myGPack {
|
|||
// STATIC: 0x01159FF0
|
||||
// GLOBAL: gl_13431
|
||||
constexpr std::uint8_t s_roundPermutation[32] = {
|
||||
16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, 5, 18, 31, 10,
|
||||
2, 8, 24, 14, 32, 27, 3, 9, 19, 13, 30, 6, 22, 11, 4, 25,
|
||||
16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, 5, 18, 31, 10, 2, 8, 24, 14, 32, 27, 3, 9, 19, 13, 30, 6, 22, 11, 4, 25,
|
||||
};
|
||||
|
||||
// STATIC: 0x0115A010
|
||||
// GLOBAL: gl_13432
|
||||
constexpr std::uint8_t s_substitution[512] = {
|
||||
14, 0, 4, 15, 13, 7, 1, 4, 2, 14, 15, 2, 11, 13, 8, 1, 3, 10, 10, 6, 6, 12, 12, 11, 5, 9, 9,
|
||||
5, 0, 3, 7, 8, 4, 15, 1, 12, 14, 8, 8, 2, 13, 4, 6, 9, 2, 1, 11, 7, 15, 5, 12, 11, 9, 3,
|
||||
7, 14, 3, 10, 10, 0, 5, 6, 0, 13, 15, 3, 1, 13, 8, 4, 14, 7, 6, 15, 11, 2, 3, 8, 4, 14, 9,
|
||||
12, 7, 0, 2, 1, 13, 10, 12, 6, 0, 9, 5, 11, 10, 5, 0, 13, 14, 8, 7, 10, 11, 1, 10, 3, 4, 15,
|
||||
13, 4, 1, 2, 5, 11, 8, 6, 12, 7, 6, 12, 9, 0, 3, 5, 2, 14, 15, 9, 10, 13, 0, 7, 9, 0, 14,
|
||||
9, 6, 3, 3, 4, 15, 6, 5, 10, 1, 2, 13, 8, 12, 5, 7, 14, 11, 12, 4, 11, 2, 15, 8, 1, 13, 1,
|
||||
6, 10, 4, 13, 9, 0, 8, 6, 15, 9, 3, 8, 0, 7, 11, 4, 1, 15, 2, 14, 12, 3, 5, 11, 10, 5, 14,
|
||||
2, 7, 12, 7, 13, 13, 8, 14, 11, 3, 5, 0, 6, 6, 15, 9, 0, 10, 3, 1, 4, 2, 7, 8, 2, 5, 12,
|
||||
11, 1, 12, 10, 4, 14, 15, 9, 10, 3, 6, 15, 9, 0, 0, 6, 12, 10, 11, 1, 7, 13, 13, 8, 15, 9, 1,
|
||||
4, 3, 5, 14, 11, 5, 12, 2, 7, 8, 2, 4, 14, 2, 14, 12, 11, 4, 2, 1, 12, 7, 4, 10, 7, 11, 13,
|
||||
6, 1, 8, 5, 5, 0, 3, 15, 15, 10, 13, 3, 0, 9, 14, 8, 9, 6, 4, 11, 2, 8, 1, 12, 11, 7, 10,
|
||||
1, 13, 14, 7, 2, 8, 13, 15, 6, 9, 15, 12, 0, 5, 9, 6, 10, 3, 4, 0, 5, 14, 3, 12, 10, 1, 15,
|
||||
10, 4, 15, 2, 9, 7, 2, 12, 6, 9, 8, 5, 0, 6, 13, 1, 3, 13, 4, 14, 14, 0, 7, 11, 5, 3, 11,
|
||||
8, 9, 4, 14, 3, 15, 2, 5, 12, 2, 9, 8, 5, 12, 15, 3, 10, 7, 11, 0, 14, 4, 1, 10, 7, 1, 6,
|
||||
13, 0, 11, 8, 6, 13, 4, 13, 11, 0, 2, 11, 14, 7, 15, 4, 0, 9, 8, 1, 13, 10, 3, 14, 12, 3, 9,
|
||||
5, 7, 12, 5, 2, 10, 15, 6, 8, 1, 6, 1, 6, 4, 11, 11, 13, 13, 8, 12, 1, 3, 4, 7, 10, 14, 7,
|
||||
10, 9, 15, 5, 6, 0, 8, 15, 0, 14, 5, 2, 9, 3, 2, 12, 13, 1, 2, 15, 8, 13, 4, 8, 6, 10, 15,
|
||||
3, 11, 7, 1, 4, 10, 12, 9, 5, 3, 6, 14, 11, 5, 0, 0, 14, 12, 9, 7, 2, 7, 2, 11, 1, 4, 14,
|
||||
1, 7, 9, 4, 12, 10, 14, 8, 2, 13, 0, 15, 6, 12, 10, 9, 13, 0, 15, 3, 3, 5, 5, 6, 8, 11,
|
||||
14, 0, 4, 15, 13, 7, 1, 4, 2, 14, 15, 2, 11, 13, 8, 1, 3, 10, 10, 6, 6, 12, 12, 11, 5, 9, 9, 5, 0, 3, 7, 8, 4, 15, 1, 12, 14,
|
||||
8, 8, 2, 13, 4, 6, 9, 2, 1, 11, 7, 15, 5, 12, 11, 9, 3, 7, 14, 3, 10, 10, 0, 5, 6, 0, 13, 15, 3, 1, 13, 8, 4, 14, 7, 6, 15,
|
||||
11, 2, 3, 8, 4, 14, 9, 12, 7, 0, 2, 1, 13, 10, 12, 6, 0, 9, 5, 11, 10, 5, 0, 13, 14, 8, 7, 10, 11, 1, 10, 3, 4, 15, 13, 4, 1,
|
||||
2, 5, 11, 8, 6, 12, 7, 6, 12, 9, 0, 3, 5, 2, 14, 15, 9, 10, 13, 0, 7, 9, 0, 14, 9, 6, 3, 3, 4, 15, 6, 5, 10, 1, 2, 13, 8,
|
||||
12, 5, 7, 14, 11, 12, 4, 11, 2, 15, 8, 1, 13, 1, 6, 10, 4, 13, 9, 0, 8, 6, 15, 9, 3, 8, 0, 7, 11, 4, 1, 15, 2, 14, 12, 3, 5,
|
||||
11, 10, 5, 14, 2, 7, 12, 7, 13, 13, 8, 14, 11, 3, 5, 0, 6, 6, 15, 9, 0, 10, 3, 1, 4, 2, 7, 8, 2, 5, 12, 11, 1, 12, 10, 4, 14,
|
||||
15, 9, 10, 3, 6, 15, 9, 0, 0, 6, 12, 10, 11, 1, 7, 13, 13, 8, 15, 9, 1, 4, 3, 5, 14, 11, 5, 12, 2, 7, 8, 2, 4, 14, 2, 14, 12,
|
||||
11, 4, 2, 1, 12, 7, 4, 10, 7, 11, 13, 6, 1, 8, 5, 5, 0, 3, 15, 15, 10, 13, 3, 0, 9, 14, 8, 9, 6, 4, 11, 2, 8, 1, 12, 11, 7,
|
||||
10, 1, 13, 14, 7, 2, 8, 13, 15, 6, 9, 15, 12, 0, 5, 9, 6, 10, 3, 4, 0, 5, 14, 3, 12, 10, 1, 15, 10, 4, 15, 2, 9, 7, 2, 12, 6,
|
||||
9, 8, 5, 0, 6, 13, 1, 3, 13, 4, 14, 14, 0, 7, 11, 5, 3, 11, 8, 9, 4, 14, 3, 15, 2, 5, 12, 2, 9, 8, 5, 12, 15, 3, 10, 7, 11,
|
||||
0, 14, 4, 1, 10, 7, 1, 6, 13, 0, 11, 8, 6, 13, 4, 13, 11, 0, 2, 11, 14, 7, 15, 4, 0, 9, 8, 1, 13, 10, 3, 14, 12, 3, 9, 5, 7,
|
||||
12, 5, 2, 10, 15, 6, 8, 1, 6, 1, 6, 4, 11, 11, 13, 13, 8, 12, 1, 3, 4, 7, 10, 14, 7, 10, 9, 15, 5, 6, 0, 8, 15, 0, 14, 5, 2,
|
||||
9, 3, 2, 12, 13, 1, 2, 15, 8, 13, 4, 8, 6, 10, 15, 3, 11, 7, 1, 4, 10, 12, 9, 5, 3, 6, 14, 11, 5, 0, 0, 14, 12, 9, 7, 2, 7,
|
||||
2, 11, 1, 4, 14, 1, 7, 9, 4, 12, 10, 14, 8, 2, 13, 0, 15, 6, 12, 10, 9, 13, 0, 15, 3, 3, 5, 5, 6, 8, 11,
|
||||
};
|
||||
|
||||
void Permute(std::uint8_t* block, const std::uint8_t* table, unsigned count) {
|
||||
std::uint8_t result[8] = {};
|
||||
|
||||
for (unsigned i = 0; i < count; ++i) {
|
||||
unsigned bit = table[i] - 1;
|
||||
if (block[bit >> 3] & (0x80u >> (bit & 7))) {
|
||||
result[i >> 3] |= static_cast<std::uint8_t>(0x80u >> (i & 7));
|
||||
}
|
||||
}
|
||||
|
||||
std::memcpy(block, result, sizeof(result));
|
||||
}
|
||||
|
||||
|
|
@ -105,7 +98,6 @@ namespace myGPack {
|
|||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// OFFSET: 0x00AE8480
|
||||
|
|
@ -118,9 +110,6 @@ namespace myGPack {
|
|||
// OFFSET: 0x00AE92F0
|
||||
// FUNCTION: fn_18105
|
||||
PakCipher::PakCipher(const std::uint8_t* key) {
|
||||
// The original key permutation ANDs into zeroed state. Every resulting
|
||||
// round key is zero, independent of the eight key bytes it reads.
|
||||
// This is intentional original behavior, not standard DES key expansion.
|
||||
(void)key;
|
||||
std::memset(this->m_roundKeys, 0, sizeof(this->m_roundKeys));
|
||||
}
|
||||
|
|
@ -133,22 +122,30 @@ namespace myGPack {
|
|||
// OFFSET: 0x00AE8E70
|
||||
// FUNCTION: fn_18101
|
||||
int PakCipher::DecodeBlock(int rounds, const std::uint8_t* input, std::uint8_t* output) const {
|
||||
std::memcpy(output, input, 8);
|
||||
std::uint32_t inputLow;
|
||||
std::uint32_t inputHigh;
|
||||
std::memcpy(&inputLow, input, sizeof(inputLow));
|
||||
std::memcpy(&inputHigh, input + 4, sizeof(inputHigh));
|
||||
std::memcpy(output, &inputLow, sizeof(inputLow));
|
||||
std::memcpy(output + 4, &inputHigh, sizeof(inputHigh));
|
||||
Permute(output, s_initialPermutation, 64);
|
||||
|
||||
for (int round = 0; round < rounds; ++round) {
|
||||
std::uint8_t expanded[8] = {};
|
||||
|
||||
for (unsigned i = 0; i < 48; ++i) {
|
||||
unsigned bit = s_expansion[i] + 31;
|
||||
if (output[bit >> 3] & (0x80u >> (bit & 7))) {
|
||||
expanded[i / 6] |= static_cast<std::uint8_t>(0x80u >> (i % 6));
|
||||
}
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < 8; ++i) {
|
||||
expanded[i] ^= this->m_roundKeys[15 - round][i];
|
||||
}
|
||||
|
||||
std::uint8_t substituted[4] = {};
|
||||
|
||||
for (unsigned i = 0; i < 8; ++i) {
|
||||
std::uint8_t value = s_substitution[64 * i + (expanded[i] >> 2)];
|
||||
if (i & 1) {
|
||||
|
|
@ -159,15 +156,18 @@ namespace myGPack {
|
|||
}
|
||||
|
||||
std::uint8_t transformed[4] = {};
|
||||
|
||||
for (unsigned i = 0; i < 32; ++i) {
|
||||
unsigned bit = s_roundPermutation[i] - 1;
|
||||
if (substituted[bit >> 3] & (0x80u >> (bit & 7))) {
|
||||
transformed[i >> 3] |= static_cast<std::uint8_t>(0x80u >> (i & 7));
|
||||
}
|
||||
}
|
||||
|
||||
std::uint8_t previous[4];
|
||||
std::memcpy(previous, output, 4);
|
||||
std::memcpy(output, output + 4, 4);
|
||||
|
||||
for (unsigned i = 0; i < 4; ++i) {
|
||||
output[i + 4] = transformed[i] ^ previous[i];
|
||||
}
|
||||
|
|
@ -176,22 +176,18 @@ namespace myGPack {
|
|||
for (unsigned i = 0; i < 4; ++i) {
|
||||
std::swap(output[i], output[i + 4]);
|
||||
}
|
||||
|
||||
Permute(output, s_finalPermutation, 64);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// OFFSET: 0x00AE84A0
|
||||
// FUNCTION: fn_18099
|
||||
int PakCipher::Decode(
|
||||
const std::uint8_t* input,
|
||||
int length,
|
||||
std::uint8_t* output,
|
||||
int* outputLength,
|
||||
int cycle
|
||||
) const {
|
||||
int PakCipher::Decode(const std::uint8_t* input, int length, std::uint8_t* output, int* outputLength, int cycle) const {
|
||||
if (!input || !output || !outputLength) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
*outputLength = length;
|
||||
if (cycle < 3) {
|
||||
cycle = 1;
|
||||
|
|
@ -206,10 +202,10 @@ namespace myGPack {
|
|||
int shuffled = 0;
|
||||
int block = 0;
|
||||
int offset = 0;
|
||||
|
||||
do {
|
||||
if (block >= 20 && block % cycle != 0) {
|
||||
if (shuffled == 7) {
|
||||
// Preserve the original store/load order, including in-place use.
|
||||
std::uint16_t pair;
|
||||
std::memcpy(&pair, input + offset + 3, 2);
|
||||
std::memcpy(output + offset, &pair, 2);
|
||||
|
|
@ -221,11 +217,12 @@ namespace myGPack {
|
|||
output[offset + 7] = SubstituteLastByte(input[offset + 7]);
|
||||
shuffled = 1;
|
||||
} else {
|
||||
std::uint32_t word;
|
||||
std::memcpy(&word, input + offset, 4);
|
||||
std::memcpy(output + offset, &word, 4);
|
||||
std::memcpy(&word, input + offset + 4, 4);
|
||||
std::memcpy(output + offset + 4, &word, 4);
|
||||
std::uint32_t low;
|
||||
std::uint32_t high;
|
||||
std::memcpy(&low, input + offset, sizeof(low));
|
||||
std::memcpy(&high, input + offset + 4, sizeof(high));
|
||||
std::memcpy(output + offset, &low, sizeof(low));
|
||||
std::memcpy(output + offset + 4, &high, sizeof(high));
|
||||
++shuffled;
|
||||
}
|
||||
} else {
|
||||
|
|
@ -235,9 +232,11 @@ namespace myGPack {
|
|||
this->DecodeBlock(1, blockInput, blockOutput);
|
||||
std::memcpy(output + offset, blockOutput, 8);
|
||||
}
|
||||
|
||||
offset += 8;
|
||||
++block;
|
||||
} while (offset < length);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
@ -248,6 +247,7 @@ namespace myGPack {
|
|||
std::memcpy(output, input, static_cast<std::uint32_t>(length));
|
||||
int offset = 0;
|
||||
int block = 0;
|
||||
|
||||
do {
|
||||
std::uint8_t blockInput[8];
|
||||
std::uint8_t decoded[8];
|
||||
|
|
@ -257,6 +257,7 @@ namespace myGPack {
|
|||
offset += 8;
|
||||
++block;
|
||||
} while (offset < length && block < 20);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
@ -264,49 +265,56 @@ namespace myGPack {
|
|||
// FUNCTION: fn_18104
|
||||
int __stdcall InitialPermutation(std::uint8_t* block) {
|
||||
std::uint8_t result[8] = {};
|
||||
|
||||
for (unsigned i = 0; i < 64; ++i) {
|
||||
unsigned bit = s_initialPermutation[i] - 1;
|
||||
if (block[bit >> 3] & (0x80u >> (bit & 7))) {
|
||||
result[i >> 3] |= static_cast<std::uint8_t>(0x80u >> (i & 7));
|
||||
}
|
||||
}
|
||||
|
||||
std::memcpy(block, result, 8);
|
||||
return *reinterpret_cast<const int*>(result + 4);
|
||||
int high;
|
||||
std::memcpy(&high, result + 4, sizeof(high));
|
||||
|
||||
return high;
|
||||
}
|
||||
|
||||
// OFFSET: 0x00AE91D0
|
||||
// FUNCTION: fn_18103
|
||||
int __stdcall FinalPermutation(std::uint8_t* block) {
|
||||
std::uint8_t result[8] = {};
|
||||
|
||||
for (unsigned i = 0; i < 64; ++i) {
|
||||
unsigned bit = s_finalPermutation[i] - 1;
|
||||
if (block[bit >> 3] & (0x80u >> (bit & 7))) {
|
||||
result[i >> 3] |= static_cast<std::uint8_t>(0x80u >> (i & 7));
|
||||
}
|
||||
}
|
||||
|
||||
std::memcpy(block, result, 8);
|
||||
return *reinterpret_cast<const int*>(result + 4);
|
||||
int high;
|
||||
std::memcpy(&high, result + 4, sizeof(high));
|
||||
|
||||
return high;
|
||||
}
|
||||
|
||||
// OFFSET: 0x00AE9020
|
||||
// FUNCTION: fn_18102
|
||||
int __stdcall EncodeBlock(
|
||||
int rounds,
|
||||
const std::uint8_t (*roundKeys)[8],
|
||||
std::uint32_t inputLow,
|
||||
std::uint32_t inputHigh,
|
||||
std::uint8_t* output
|
||||
) {
|
||||
int __stdcall EncodeBlock(int rounds, const std::uint8_t (*roundKeys)[8], std::uint32_t inputLow, std::uint32_t inputHigh, std::uint8_t* output) {
|
||||
std::memcpy(output, &inputLow, 4);
|
||||
std::memcpy(output + 4, &inputHigh, 4);
|
||||
InitialPermutation(output);
|
||||
|
||||
if (rounds > 0) {
|
||||
std::uint32_t left = *reinterpret_cast<const std::uint32_t*>(output);
|
||||
std::uint32_t right = *reinterpret_cast<const std::uint32_t*>(output + 4);
|
||||
std::uint32_t left;
|
||||
std::uint32_t right;
|
||||
std::memcpy(&left, output, sizeof(left));
|
||||
std::memcpy(&right, output + 4, sizeof(right));
|
||||
|
||||
for (int round = 0; round < rounds; ++round) {
|
||||
std::uint8_t expanded[8] = {};
|
||||
|
||||
for (unsigned i = 0; i < 48; ++i) {
|
||||
unsigned bit = s_expansion[i] + 31;
|
||||
if (output[bit >> 3] & (0x80u >> (bit & 7))) {
|
||||
|
|
@ -319,6 +327,7 @@ namespace myGPack {
|
|||
}
|
||||
|
||||
std::uint8_t substituted[4] = {};
|
||||
|
||||
for (unsigned i = 0; i < 8; ++i) {
|
||||
std::uint8_t value = s_substitution[64 * i + (expanded[i] >> 2)];
|
||||
if (i & 1) {
|
||||
|
|
@ -329,6 +338,7 @@ namespace myGPack {
|
|||
}
|
||||
|
||||
std::uint8_t transformed[4] = {};
|
||||
|
||||
for (unsigned i = 0; i < 32; ++i) {
|
||||
unsigned bit = s_roundPermutation[i] - 1;
|
||||
if (substituted[bit >> 3] & (0x80u >> (bit & 7))) {
|
||||
|
|
@ -336,19 +346,24 @@ namespace myGPack {
|
|||
}
|
||||
}
|
||||
|
||||
std::uint32_t newRight = left ^ *reinterpret_cast<const std::uint32_t*>(transformed);
|
||||
std::uint32_t transformedWord;
|
||||
std::memcpy(&transformedWord, transformed, sizeof(transformedWord));
|
||||
std::uint32_t newRight = left ^ transformedWord;
|
||||
left = right;
|
||||
right = newRight;
|
||||
*reinterpret_cast<std::uint32_t*>(output) = left;
|
||||
*reinterpret_cast<std::uint32_t*>(output + 4) = right;
|
||||
std::memcpy(output, &left, sizeof(left));
|
||||
std::memcpy(output + 4, &right, sizeof(right));
|
||||
}
|
||||
|
||||
*reinterpret_cast<std::uint32_t*>(output) = right;
|
||||
*reinterpret_cast<std::uint32_t*>(output + 4) = left;
|
||||
std::memcpy(output, &right, sizeof(right));
|
||||
std::memcpy(output + 4, &left, sizeof(left));
|
||||
} else {
|
||||
std::uint32_t temp = *reinterpret_cast<const std::uint32_t*>(output);
|
||||
*reinterpret_cast<std::uint32_t*>(output) = *reinterpret_cast<const std::uint32_t*>(output + 4);
|
||||
*reinterpret_cast<std::uint32_t*>(output + 4) = temp;
|
||||
std::uint32_t left;
|
||||
std::uint32_t right;
|
||||
std::memcpy(&left, output, sizeof(left));
|
||||
std::memcpy(&right, output + 4, sizeof(right));
|
||||
std::memcpy(output, &right, sizeof(right));
|
||||
std::memcpy(output + 4, &left, sizeof(left));
|
||||
}
|
||||
|
||||
FinalPermutation(output);
|
||||
|
|
@ -382,5 +397,4 @@ namespace myGPack {
|
|||
|
||||
return key;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,9 +5,6 @@
|
|||
|
||||
namespace myGPack {
|
||||
|
||||
// Reconstructed semantic class name; original symbol unavailable.
|
||||
// The original stream routine processes complete eight-byte blocks, including
|
||||
// one block for length <= 0. Callers must provide corresponding buffer space.
|
||||
class PakCipher {
|
||||
public:
|
||||
PakCipher();
|
||||
|
|
@ -25,13 +22,7 @@ namespace myGPack {
|
|||
std::uint8_t* __stdcall DerivePakKey(const char* name, std::uint8_t* key);
|
||||
int __stdcall InitialPermutation(std::uint8_t* block);
|
||||
int __stdcall FinalPermutation(std::uint8_t* block);
|
||||
int __stdcall EncodeBlock(
|
||||
int rounds,
|
||||
const std::uint8_t (*roundKeys)[8],
|
||||
std::uint32_t inputLow,
|
||||
std::uint32_t inputHigh,
|
||||
std::uint8_t* output
|
||||
);
|
||||
int __stdcall EncodeBlock(int rounds, const std::uint8_t (*roundKeys)[8], std::uint32_t inputLow, std::uint32_t inputHigh, std::uint8_t* output);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,13 +1,10 @@
|
|||
#include "Archive/PakFile.h"
|
||||
|
||||
#include <bit>
|
||||
|
||||
// OFFSET: 0x005EF660
|
||||
// FUNCTION: fn_04009
|
||||
CPakFile::~CPakFile() = default;
|
||||
|
||||
namespace myGPack {
|
||||
|
||||
// OFFSET: 0x005F7790
|
||||
// FUNCTION: fn_04046
|
||||
CReadPakFile::CReadPakFile() : m_handle(INVALID_HANDLE_VALUE), m_size(0) {
|
||||
|
|
@ -31,7 +28,6 @@ namespace myGPack {
|
|||
// OFFSET: 0x005F7810
|
||||
// FUNCTION: fn_04047
|
||||
void CReadPakFile::Close() {
|
||||
// The original tests for null, not INVALID_HANDLE_VALUE.
|
||||
if (this->m_handle) {
|
||||
CloseHandle(this->m_handle);
|
||||
this->m_handle = nullptr;
|
||||
|
|
@ -41,18 +37,15 @@ namespace myGPack {
|
|||
// OFFSET: 0x005F7890
|
||||
// FUNCTION: fn_04048
|
||||
bool CWritePakFile::Open(const char* filename) {
|
||||
this->m_handle = CreateFileA(
|
||||
filename, GENERIC_READ | GENERIC_WRITE, 0, nullptr, OPEN_ALWAYS, FILE_FLAG_WRITE_THROUGH | FILE_ATTRIBUTE_NORMAL,
|
||||
nullptr
|
||||
);
|
||||
this->m_handle = CreateFileA(filename, GENERIC_READ | GENERIC_WRITE, 0, nullptr, OPEN_ALWAYS, FILE_FLAG_WRITE_THROUGH | FILE_ATTRIBUTE_NORMAL, nullptr);
|
||||
if (this->m_handle == INVALID_HANDLE_VALUE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
LARGE_INTEGER size;
|
||||
// The original does not check GetFileSizeEx's return value.
|
||||
|
||||
GetFileSizeEx(this->m_handle, &size);
|
||||
this->m_size = std::bit_cast<std::uint64_t>(size.QuadPart);
|
||||
this->m_size = static_cast<std::uint64_t>(size.QuadPart);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -66,14 +59,15 @@ namespace myGPack {
|
|||
this->m_buffer.resize(length);
|
||||
|
||||
LARGE_INTEGER position;
|
||||
position.QuadPart = std::bit_cast<std::int64_t>(offset);
|
||||
// Seeking errors are not checked before the original ReadFile call.
|
||||
position.QuadPart = static_cast<std::int64_t>(offset);
|
||||
|
||||
SetFilePointerEx(this->m_handle, position, nullptr, FILE_BEGIN);
|
||||
|
||||
DWORD read;
|
||||
if (ReadFile(this->m_handle, this->m_buffer.data(), length, &read, nullptr) && read == length) {
|
||||
return this->m_buffer.data();
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
|
@ -81,7 +75,7 @@ namespace myGPack {
|
|||
// FUNCTION: fn_04050
|
||||
bool CWritePakFile::Write(std::uint64_t offset, const void* bytes, std::uint32_t length) {
|
||||
LARGE_INTEGER position;
|
||||
position.QuadPart = std::bit_cast<std::int64_t>(offset);
|
||||
position.QuadPart = static_cast<std::int64_t>(offset);
|
||||
SetFilePointerEx(this->m_handle, position, nullptr, FILE_BEGIN);
|
||||
|
||||
DWORD written;
|
||||
|
|
@ -93,7 +87,7 @@ namespace myGPack {
|
|||
if (this->m_size < end) {
|
||||
this->m_size = end;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,8 +5,6 @@
|
|||
#include <vector>
|
||||
#include <windows.h>
|
||||
|
||||
// Class names and inheritance are established by original RTTI.
|
||||
// Method and member names are reconstructed from their behavior.
|
||||
class CPakFile {
|
||||
public:
|
||||
virtual ~CPakFile();
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@
|
|||
#include <cstring>
|
||||
|
||||
namespace myGPack {
|
||||
|
||||
// OFFSET: 0x00AECE00
|
||||
// FUNCTION: fn_18145
|
||||
PakName::PakName() {
|
||||
|
|
@ -19,14 +18,15 @@ namespace myGPack {
|
|||
}
|
||||
|
||||
void AssignNameKey(std::uint32_t& result, char* destination, const char* source) {
|
||||
// Source helper: copies through NUL without bounds checking.
|
||||
std::strcpy(destination, source);
|
||||
_strlwr(destination);
|
||||
const std::size_t length = std::strlen(destination);
|
||||
std::uint32_t hash = 5381;
|
||||
|
||||
for (std::size_t i = 0; i < length; ++i) {
|
||||
hash = 33 * hash + static_cast<std::int8_t>(destination[i]);
|
||||
}
|
||||
|
||||
result = hash;
|
||||
}
|
||||
|
||||
|
|
@ -48,7 +48,7 @@ namespace myGPack {
|
|||
if (this->m_hash == other.m_hash) {
|
||||
return std::strcmp(this->m_name, other.m_name) < 0;
|
||||
}
|
||||
|
||||
return this->m_hash < other.m_hash;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,10 +6,8 @@
|
|||
|
||||
namespace myGPack {
|
||||
|
||||
// Shared machine algorithm used with different owner-reserved buffer extents.
|
||||
void AssignNameKey(std::uint32_t& hash, char* destination, const char* source);
|
||||
|
||||
// Reconstructed name for the key embedded at archive entry offset 0x1C.
|
||||
class PakName {
|
||||
public:
|
||||
PakName();
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ PakRegistry::~PakRegistry() {
|
|||
delete archive.first;
|
||||
delete archive.second;
|
||||
}
|
||||
|
||||
this->m_archives.clear();
|
||||
}
|
||||
|
||||
|
|
@ -23,6 +24,7 @@ bool PakRegistry::Add(const char* filename) {
|
|||
if (file) {
|
||||
file->Open(filename);
|
||||
}
|
||||
|
||||
this->m_archives.emplace_front(file, archive);
|
||||
return this->m_archives.front().second->Open(this->m_archives.front().first);
|
||||
}
|
||||
|
|
@ -79,6 +81,7 @@ bool PakRegistry::Exists(const char* filename, bool looseOnly) const {
|
|||
if (search == INVALID_HANDLE_VALUE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
FindClose(search);
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
19
Source/Client/Application/ApplicationActivation.cpp
Normal file
19
Source/Client/Application/ApplicationActivation.cpp
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
#include "Client/Application/ApplicationActivation.h"
|
||||
#include "Client/Application/ApplicationWindow.h"
|
||||
#include "Contents/Configuration/ServiceOptions.h"
|
||||
|
||||
// OFFSET: 0x00E5A190
|
||||
// FUNCTION: fn_24369
|
||||
void ApplicationActivation::Set(int value) {
|
||||
this->active = value;
|
||||
if (value != 0) {
|
||||
SetPriorityClass(GetCurrentProcess(), this->priority);
|
||||
if (this->service.Get(ServiceOption::ConfineCursor) != 0) {
|
||||
ClipApplicationCursor(this->window);
|
||||
}
|
||||
} else {
|
||||
SetPriorityClass(GetCurrentProcess(), IDLE_PRIORITY_CLASS);
|
||||
ClipCursor(nullptr);
|
||||
this->automaticSkills.DisableAll();
|
||||
}
|
||||
}
|
||||
17
Source/Client/Application/ApplicationActivation.h
Normal file
17
Source/Client/Application/ApplicationActivation.h
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
#ifndef RAGNAROK_SOURCE_CLIENT_APPLICATION_APPLICATIONACTIVATION_H
|
||||
#define RAGNAROK_SOURCE_CLIENT_APPLICATION_APPLICATIONACTIVATION_H
|
||||
|
||||
#include "Contents/Skills/AutomaticSkills.h"
|
||||
#include "Contents/Configuration/ServiceOptions.h"
|
||||
|
||||
struct ApplicationActivation {
|
||||
HWND& window;
|
||||
const DWORD& priority;
|
||||
int& active;
|
||||
ServiceOptions& service;
|
||||
AutomaticSkills& automaticSkills;
|
||||
|
||||
void Set(int value);
|
||||
};
|
||||
|
||||
#endif
|
||||
46
Source/Client/Application/ApplicationMessages.cpp
Normal file
46
Source/Client/Application/ApplicationMessages.cpp
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
#include "Client/Application/ApplicationMessages.h"
|
||||
#include "Client/Application/ApplicationWindow.h"
|
||||
#include "Client/Input/TraditionalKeyInput.h"
|
||||
#include "Contents/Configuration/ServiceOptions.h"
|
||||
|
||||
#include <cstdint>
|
||||
#include <imm.h>
|
||||
|
||||
// OFFSET: 0x00E57380
|
||||
// FUNCTION: fn_24357
|
||||
void ApplicationMessages::Pump() {
|
||||
MSG message;
|
||||
|
||||
while (PeekMessageA(&message, nullptr, 0, 0, PM_REMOVE)) {
|
||||
if (message.message == WM_KEYDOWN && message.wParam == VK_PROCESSKEY) {
|
||||
const UINT key = ImmGetVirtualKey(message.hwnd);
|
||||
if (this->traditional) {
|
||||
this->traditional->Key(static_cast<int>(key));
|
||||
}
|
||||
}
|
||||
|
||||
TranslateMessage(&message);
|
||||
DispatchMessageA(&message);
|
||||
}
|
||||
|
||||
if (this->dragging == 1) {
|
||||
POINT point;
|
||||
GetCursorPos(&point);
|
||||
const int deltaX = point.x - this->dragStart.x;
|
||||
const int deltaY = point.y - this->dragStart.y;
|
||||
|
||||
if (deltaX != 0 || deltaY != 0) {
|
||||
MoveWindow(
|
||||
this->window, this->dragRectangle.left + deltaX, this->dragRectangle.top + deltaY, this->dragRectangle.right - this->dragRectangle.left,
|
||||
this->dragRectangle.bottom - this->dragRectangle.top, TRUE
|
||||
);
|
||||
}
|
||||
|
||||
if ((GetAsyncKeyState(VK_LBUTTON) & 0x8000) == 0) {
|
||||
this->dragging = 0;
|
||||
if (this->service.Get(ServiceOption::ConfineCursor) != 0) {
|
||||
ClipApplicationCursor(this->window);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
20
Source/Client/Application/ApplicationMessages.h
Normal file
20
Source/Client/Application/ApplicationMessages.h
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
#ifndef RAGNAROK_SOURCE_CLIENT_APPLICATION_APPLICATIONMESSAGES_H
|
||||
#define RAGNAROK_SOURCE_CLIENT_APPLICATION_APPLICATIONMESSAGES_H
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
struct TraditionalKeyInput;
|
||||
struct ServiceOptions;
|
||||
|
||||
struct ApplicationMessages {
|
||||
HWND& window;
|
||||
unsigned char& dragging;
|
||||
POINT& dragStart;
|
||||
RECT& dragRectangle;
|
||||
TraditionalKeyInput* const& traditional;
|
||||
ServiceOptions& service;
|
||||
|
||||
void Pump();
|
||||
};
|
||||
|
||||
#endif
|
||||
24
Source/Client/Application/ApplicationWindow.cpp
Normal file
24
Source/Client/Application/ApplicationWindow.cpp
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
#include "Client/Application/ApplicationWindow.h"
|
||||
|
||||
// OFFSET: 0x03DE9F37
|
||||
// FUNCTION: fn_45411
|
||||
HWND CreateApplicationWindow(
|
||||
DWORD extendedStyle, const char* className, const char*, DWORD style, int x, int y, int width, int height, HWND parent, HMENU menu, HINSTANCE instance,
|
||||
void* parameter
|
||||
) {
|
||||
return CreateWindowExA(extendedStyle, className, "Ragnarok 2026", style | WS_SYSMENU, x, y, width, height, parent, menu, instance, parameter);
|
||||
}
|
||||
|
||||
// OFFSET: 0x00E57DD0
|
||||
// FUNCTION: fn_24360
|
||||
BOOL ClipApplicationCursor(HWND window) {
|
||||
RECT rectangle;
|
||||
GetClientRect(window, &rectangle);
|
||||
POINT first{rectangle.left, rectangle.top};
|
||||
POINT last{rectangle.right, rectangle.bottom};
|
||||
ClientToScreen(window, &first);
|
||||
ClientToScreen(window, &last);
|
||||
|
||||
RECT clip{first.x, first.y, last.x, last.y};
|
||||
return ClipCursor(&clip);
|
||||
}
|
||||
13
Source/Client/Application/ApplicationWindow.h
Normal file
13
Source/Client/Application/ApplicationWindow.h
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
#ifndef RAGNAROK_SOURCE_CLIENT_APPLICATION_APPLICATIONWINDOW_H
|
||||
#define RAGNAROK_SOURCE_CLIENT_APPLICATION_APPLICATIONWINDOW_H
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
HWND CreateApplicationWindow(
|
||||
DWORD extendedStyle, const char* className, const char* ignoredTitle, DWORD style, int x, int y, int width, int height, HWND parent, HMENU menu,
|
||||
HINSTANCE instance, void* parameter
|
||||
);
|
||||
|
||||
BOOL ClipApplicationCursor(HWND window);
|
||||
|
||||
#endif
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
#include "Client/ErrorDialog.h"
|
||||
#include "Client/Application/ErrorDialog.h"
|
||||
#include "Render/RenderSystemBase.h"
|
||||
|
||||
// OFFSET: 0x00AD6360
|
||||
|
|
@ -7,5 +7,6 @@ int ShowErrorDialog(CRenderSystemBase* renderSystem, const char* text, UINT type
|
|||
if (renderSystem) {
|
||||
renderSystem->PrepareErrorDialog();
|
||||
}
|
||||
|
||||
return MessageBoxA(nullptr, text, "Error", type);
|
||||
}
|
||||
10
Source/Client/Application/ErrorDialog.h
Normal file
10
Source/Client/Application/ErrorDialog.h
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
#ifndef RAGNAROK_SOURCE_CLIENT_APPLICATION_ERRORDIALOG_H
|
||||
#define RAGNAROK_SOURCE_CLIENT_APPLICATION_ERRORDIALOG_H
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
class CRenderSystemBase;
|
||||
|
||||
int ShowErrorDialog(CRenderSystemBase* renderSystem, const char* text, UINT type);
|
||||
|
||||
#endif
|
||||
40
Source/Client/Application/Launcher.cpp
Normal file
40
Source/Client/Application/Launcher.cpp
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
#include "Client/Application/Launcher.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <windows.h>
|
||||
|
||||
// OFFSET: 0x00E58820
|
||||
// FUNCTION: fn_24363
|
||||
bool RestartFromCommandLine(char* commandLine) {
|
||||
char* marker = std::strstr(commandLine, "/launcherRESTART:");
|
||||
if (!marker) {
|
||||
return false;
|
||||
}
|
||||
|
||||
STARTUPINFOA startup = {};
|
||||
startup.cb = sizeof(startup);
|
||||
startup.dwFlags = STARTF_USESHOWWINDOW;
|
||||
startup.wShowWindow = SW_SHOWNORMAL;
|
||||
PROCESS_INFORMATION process;
|
||||
|
||||
CreateProcessA(nullptr, marker + std::strlen("/launcherRESTART:"), nullptr, nullptr, FALSE, 0, nullptr, nullptr, &startup, &process);
|
||||
CloseHandle(process.hProcess);
|
||||
CloseHandle(process.hThread);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// OFFSET: 0x00E5D390
|
||||
// FUNCTION: fn_24380
|
||||
void ExitForProtectionCheck(const char* commandLine) {
|
||||
if (std::strstr(commandLine, "/check_themida")) {
|
||||
ExitProcess(0);
|
||||
}
|
||||
}
|
||||
|
||||
// OFFSET: 0x00E5D390
|
||||
// FUNCTION: fn_24380
|
||||
bool AcquireInstanceMutex(HANDLE* mutex) {
|
||||
*mutex = CreateMutexA(nullptr, TRUE, "MutexInit");
|
||||
return GetLastError() != ERROR_ALREADY_EXISTS;
|
||||
}
|
||||
11
Source/Client/Application/Launcher.h
Normal file
11
Source/Client/Application/Launcher.h
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
#ifndef RAGNAROK_SOURCE_CLIENT_APPLICATION_LAUNCHER_H
|
||||
#define RAGNAROK_SOURCE_CLIENT_APPLICATION_LAUNCHER_H
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
bool RestartFromCommandLine(char* commandLine);
|
||||
|
||||
void ExitForProtectionCheck(const char* commandLine);
|
||||
bool AcquireInstanceMutex(HANDLE* mutex);
|
||||
|
||||
#endif
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
#include "Client/UnhandledExceptionHandler.h"
|
||||
#include "Client/Mode/ActiveGameMode.h"
|
||||
#include "Client/Application/UnhandledExceptionHandler.h"
|
||||
|
||||
#include <windows.h>
|
||||
#include <dbghelp.h>
|
||||
|
|
@ -56,35 +57,36 @@ extern int64_t g_loginTimeTicks;
|
|||
// GLOBAL: gl_24474
|
||||
extern const uint8_t g_session[];
|
||||
|
||||
// STATIC: 0x013495b8
|
||||
// GLOBAL: gl_24475
|
||||
extern const uint8_t g_world[];
|
||||
|
||||
namespace {
|
||||
int ReadPlayerJob() {
|
||||
return *reinterpret_cast<const int*>(reinterpret_cast<uintptr_t>(g_session) + 0x1628);
|
||||
int job;
|
||||
std::memcpy(&job, g_session + 0x1628, sizeof(job));
|
||||
return job;
|
||||
}
|
||||
|
||||
const char* ReadPlayerJobName(int jobId) {
|
||||
const auto* const* namesBegin = *reinterpret_cast<const char* const* const*>(reinterpret_cast<uintptr_t>(g_session) + 0xFA8);
|
||||
const auto* const* namesEnd = *reinterpret_cast<const char* const* const*>(reinterpret_cast<uintptr_t>(g_session) + 0xFAC);
|
||||
const char* const* namesBegin;
|
||||
const char* const* namesEnd;
|
||||
std::memcpy(&namesBegin, g_session + 0xFA8, sizeof(namesBegin));
|
||||
std::memcpy(&namesEnd, g_session + 0xFAC, sizeof(namesEnd));
|
||||
|
||||
if (!namesBegin || !namesEnd || namesBegin >= namesEnd) {
|
||||
return "";
|
||||
}
|
||||
|
||||
size_t count = namesEnd - namesBegin;
|
||||
if (static_cast<size_t>(jobId) >= count || !namesBegin[jobId]) {
|
||||
return "";
|
||||
}
|
||||
|
||||
return namesBegin[jobId];
|
||||
}
|
||||
|
||||
const char* ReadCurrentMapName() {
|
||||
if (*reinterpret_cast<const int*>(reinterpret_cast<uintptr_t>(g_world) + 0x58) == 1) {
|
||||
void* zone = *reinterpret_cast<void* const*>(reinterpret_cast<uintptr_t>(g_world) + 0x04);
|
||||
if (zone != nullptr) {
|
||||
return reinterpret_cast<const char*>(reinterpret_cast<uintptr_t>(zone) + 0x68);
|
||||
}
|
||||
if (g_world.state == 1 && g_world.gameMode != nullptr) {
|
||||
return reinterpret_cast<const char*>(g_world.gameMode) + 0x68;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
|
@ -149,6 +151,7 @@ int CleanupUnhandledExceptionHandler() {
|
|||
delete g_unhandledExceptionHandler;
|
||||
g_unhandledExceptionHandler = nullptr;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -216,13 +219,7 @@ BOOL CALLBACK EnumerateLoadedModulesCallback(PCSTR moduleName, ULONG moduleBase,
|
|||
|
||||
// OFFSET: 0x00635E00
|
||||
// FUNCTION: fn_04707
|
||||
void __cdecl InvalidParameterHandler(
|
||||
const wchar_t* expression,
|
||||
const wchar_t* function,
|
||||
const wchar_t* file,
|
||||
unsigned int line,
|
||||
uintptr_t pReserved
|
||||
) {
|
||||
void __cdecl InvalidParameterHandler(const wchar_t* expression, const wchar_t* function, const wchar_t* file, unsigned int line, uintptr_t pReserved) {
|
||||
EXCEPTION_RECORD record = {};
|
||||
CONTEXT context = {};
|
||||
EXCEPTION_POINTERS exceptionInfo = {&record, &context};
|
||||
|
|
@ -262,17 +259,14 @@ LONG WINAPI TopLevelExceptionFilter(EXCEPTION_POINTERS* exceptionInfo) {
|
|||
|
||||
if (dbgHelp != nullptr) {
|
||||
auto pStackWalk = reinterpret_cast<BOOL(WINAPI*)(
|
||||
DWORD, HANDLE, HANDLE, LPSTACKFRAME, PVOID, PREAD_PROCESS_MEMORY_ROUTINE,
|
||||
PFUNCTION_TABLE_ACCESS_ROUTINE, PGET_MODULE_BASE_ROUTINE, PTRANSLATE_ADDRESS_ROUTINE
|
||||
DWORD, HANDLE, HANDLE, LPSTACKFRAME, PVOID, PREAD_PROCESS_MEMORY_ROUTINE, PFUNCTION_TABLE_ACCESS_ROUTINE, PGET_MODULE_BASE_ROUTINE,
|
||||
PTRANSLATE_ADDRESS_ROUTINE
|
||||
)>(GetProcAddress(dbgHelp, "StackWalk"));
|
||||
|
||||
auto pGetTimestamp = reinterpret_cast<DWORD(WINAPI*)(HMODULE)>(
|
||||
GetProcAddress(dbgHelp, "GetTimestampForLoadedLibrary")
|
||||
);
|
||||
auto pGetTimestamp = reinterpret_cast<DWORD(WINAPI*)(HMODULE)>(GetProcAddress(dbgHelp, "GetTimestampForLoadedLibrary"));
|
||||
|
||||
auto pEnumerateLoadedModules = reinterpret_cast<BOOL(WINAPI*)(
|
||||
HANDLE, PENUMLOADED_MODULES_CALLBACK, PVOID
|
||||
)>(GetProcAddress(dbgHelp, "EnumerateLoadedModules"));
|
||||
auto pEnumerateLoadedModules =
|
||||
reinterpret_cast<BOOL(WINAPI*)(HANDLE, PENUMLOADED_MODULES_CALLBACK, PVOID)>(GetProcAddress(dbgHelp, "EnumerateLoadedModules"));
|
||||
|
||||
HMODULE module = GetModuleHandleA(nullptr);
|
||||
CHAR filename[256] = {};
|
||||
|
|
@ -281,7 +275,9 @@ LONG WINAPI TopLevelExceptionFilter(EXCEPTION_POINTERS* exceptionInfo) {
|
|||
DWORD timestamp = pGetTimestamp ? pGetTimestamp(module) : 0;
|
||||
sprintf(&g_crashString[strlen(g_crashString)], "Module Name: %s\r\n", filename);
|
||||
|
||||
const char* timeString = _ctime32(reinterpret_cast<const __time32_t*>(×tamp));
|
||||
__time32_t timestampTime;
|
||||
std::memcpy(×tampTime, ×tamp, sizeof(timestampTime));
|
||||
const char* timeString = _ctime32(×tampTime);
|
||||
sprintf(&g_crashString[strlen(g_crashString)], "Time Stamp: 0x%08x - %s\r\n", timestamp, timeString);
|
||||
sprintf(&g_crashString[strlen(g_crashString)], "Version: 0x%08x\r\n", g_clientVersion);
|
||||
sprintf(&g_crashString[strlen(g_crashString)], "\r\n");
|
||||
|
|
@ -310,6 +306,7 @@ LONG WINAPI TopLevelExceptionFilter(EXCEPTION_POINTERS* exceptionInfo) {
|
|||
if (frame.AddrPC.Offset == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (!pStackWalk(IMAGE_FILE_MACHINE_I386, process, thread, &frame, context, nullptr, nullptr, nullptr, nullptr)) {
|
||||
break;
|
||||
}
|
||||
|
|
@ -322,26 +319,28 @@ LONG WINAPI TopLevelExceptionFilter(EXCEPTION_POINTERS* exceptionInfo) {
|
|||
const auto* stack = reinterpret_cast<const unsigned char*>(context->Esp);
|
||||
sprintf(&g_crashString[strlen(g_crashString)], "\r\n");
|
||||
sprintf(
|
||||
&g_crashString[strlen(g_crashString)],
|
||||
"stack %08x - %08x\r\n",
|
||||
static_cast<unsigned int>(reinterpret_cast<uintptr_t>(stack)),
|
||||
&g_crashString[strlen(g_crashString)], "stack %08x - %08x\r\n", static_cast<unsigned int>(reinterpret_cast<uintptr_t>(stack)),
|
||||
static_cast<unsigned int>(reinterpret_cast<uintptr_t>(stack + 1024))
|
||||
);
|
||||
|
||||
for (int i = 0; i < 16; ++i) {
|
||||
sprintf(&g_crashString[strlen(g_crashString)], "%08X : ", static_cast<unsigned int>(reinterpret_cast<uintptr_t>(stack)));
|
||||
|
||||
for (int j = 0; j < 16; ++j) {
|
||||
sprintf(&g_crashString[strlen(g_crashString)], "%02X ", *stack++);
|
||||
}
|
||||
|
||||
sprintf(&g_crashString[strlen(g_crashString)], "\r\n");
|
||||
}
|
||||
|
||||
sprintf(&g_crashString[strlen(g_crashString)], "\r\nLaunch Info \r\n");
|
||||
int launchIndex = 0;
|
||||
|
||||
for (int k = 0; k < 4; ++k) {
|
||||
for (int m = 0; m < 8; ++m) {
|
||||
sprintf(&g_crashString[strlen(g_crashString)], "%04X ", g_launchInfo[launchIndex++]);
|
||||
}
|
||||
|
||||
sprintf(&g_crashString[strlen(g_crashString)], "\r\n");
|
||||
}
|
||||
|
||||
|
|
@ -354,12 +353,7 @@ LONG WINAPI TopLevelExceptionFilter(EXCEPTION_POINTERS* exceptionInfo) {
|
|||
sprintf(&g_crashString[strlen(g_crashString)], "%s %d %d\r\n", mapName, g_playerX, g_playerY);
|
||||
}
|
||||
|
||||
sprintf(
|
||||
&g_crashString[strlen(g_crashString)],
|
||||
"\r\n%I64d - %I64d",
|
||||
g_startTimeTicks / 10000000LL,
|
||||
g_loginTimeTicks / 10000000LL
|
||||
);
|
||||
sprintf(&g_crashString[strlen(g_crashString)], "\r\n%I64d - %I64d", g_startTimeTicks / 10000000LL, g_loginTimeTicks / 10000000LL);
|
||||
|
||||
int64_t reportTime = _Xtime_get_ticks() / 10000000LL;
|
||||
PROCESS_MEMORY_COUNTERS memCounters = {};
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
#ifndef RAGNAROK_SOURCE_CLIENT_UNHANDLEDEXCEPTIONHANDLER_H
|
||||
#define RAGNAROK_SOURCE_CLIENT_UNHANDLEDEXCEPTIONHANDLER_H
|
||||
#ifndef RAGNAROK_SOURCE_CLIENT_APPLICATION_UNHANDLEDEXCEPTIONHANDLER_H
|
||||
#define RAGNAROK_SOURCE_CLIENT_APPLICATION_UNHANDLEDEXCEPTIONHANDLER_H
|
||||
|
||||
#include <windows.h>
|
||||
#include <cstdint>
|
||||
|
|
@ -39,13 +39,7 @@ BOOL CALLBACK EnumerateLoadedModulesCallback(PCSTR moduleName, ULONG moduleBase,
|
|||
|
||||
// OFFSET: 0x00635E00
|
||||
// FUNCTION: fn_04707
|
||||
void __cdecl InvalidParameterHandler(
|
||||
const wchar_t* expression,
|
||||
const wchar_t* function,
|
||||
const wchar_t* file,
|
||||
unsigned int line,
|
||||
uintptr_t pReserved
|
||||
);
|
||||
void __cdecl InvalidParameterHandler(const wchar_t* expression, const wchar_t* function, const wchar_t* file, unsigned int line, uintptr_t pReserved);
|
||||
|
||||
// OFFSET: 0x00635E90
|
||||
// FUNCTION: fn_04708
|
||||
|
|
@ -55,4 +49,4 @@ void __cdecl PurecallHandler();
|
|||
// FUNCTION: fn_04709
|
||||
LONG WINAPI TopLevelExceptionFilter(EXCEPTION_POINTERS* exceptionInfo);
|
||||
|
||||
#endif // RAGNAROK_SOURCE_CLIENT_UNHANDLEDEXCEPTIONHANDLER_H
|
||||
#endif
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
#include "Client/ApplicationActivation.h"
|
||||
#include "Client/ApplicationWindow.h"
|
||||
|
||||
namespace client {
|
||||
// OFFSET: 0x00E5A190
|
||||
// FUNCTION: fn_24369
|
||||
void ApplicationActivation::Set(int value) {
|
||||
this->active = value;
|
||||
if (value != 0) {
|
||||
SetPriorityClass(GetCurrentProcess(), this->priority);
|
||||
if (this->service.Get(271) != 0) {
|
||||
ClipApplicationCursor(this->window);
|
||||
}
|
||||
} else {
|
||||
SetPriorityClass(GetCurrentProcess(), IDLE_PRIORITY_CLASS);
|
||||
ClipCursor(nullptr);
|
||||
this->automaticSkills.DisableAll();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
#ifndef RAGNAROK_SOURCE_CLIENT_APPLICATIONACTIVATION_H
|
||||
#define RAGNAROK_SOURCE_CLIENT_APPLICATIONACTIVATION_H
|
||||
|
||||
#include "Contents/AutomaticSkills.h"
|
||||
#include "Contents/ServiceOptions.h"
|
||||
|
||||
namespace client {
|
||||
// Borrowed original main-window/priority/active globals and concrete owners.
|
||||
struct ApplicationActivation {
|
||||
HWND& window;
|
||||
const DWORD& priority;
|
||||
int& active;
|
||||
ServiceOptions& service;
|
||||
AutomaticSkills& automaticSkills;
|
||||
|
||||
// Publishes value verbatim. Nonzero restores configured process priority
|
||||
// and clips only when option 271 is enabled. Zero selects idle priority,
|
||||
// releases clipping, then cancels automatic skills through their connection.
|
||||
void Set(int value);
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,47 +0,0 @@
|
|||
#include "Client/ApplicationMessages.h"
|
||||
#include "Client/ApplicationWindow.h"
|
||||
#include "Client/TraditionalKeyInput.h"
|
||||
#include "Contents/ServiceOptions.h"
|
||||
|
||||
#include <cstdint>
|
||||
#include <imm.h>
|
||||
|
||||
namespace client {
|
||||
// OFFSET: 0x00E57380
|
||||
// FUNCTION: fn_24357
|
||||
void ApplicationMessages::Pump() {
|
||||
MSG message;
|
||||
while (PeekMessageA(&message, nullptr, 0, 0, PM_REMOVE)) {
|
||||
if (message.message == WM_KEYDOWN && message.wParam == VK_PROCESSKEY) {
|
||||
const UINT key = ImmGetVirtualKey(message.hwnd);
|
||||
if (this->traditional) {
|
||||
this->traditional->Key(static_cast<int>(key));
|
||||
}
|
||||
}
|
||||
|
||||
TranslateMessage(&message);
|
||||
DispatchMessageA(&message);
|
||||
}
|
||||
|
||||
if (this->dragging == 1) {
|
||||
POINT point;
|
||||
GetCursorPos(&point);
|
||||
const int deltaX = point.x - this->dragStart.x;
|
||||
const int deltaY = point.y - this->dragStart.y;
|
||||
if (deltaX != 0 || deltaY != 0) {
|
||||
MoveWindow(
|
||||
this->window, this->dragRectangle.left + deltaX, this->dragRectangle.top + deltaY,
|
||||
this->dragRectangle.right - this->dragRectangle.left, this->dragRectangle.bottom - this->dragRectangle.top,
|
||||
TRUE
|
||||
);
|
||||
}
|
||||
|
||||
if ((GetAsyncKeyState(VK_LBUTTON) & 0x8000) == 0) {
|
||||
this->dragging = 0;
|
||||
if (this->service.Get(271) != 0) {
|
||||
ClipApplicationCursor(this->window);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
#ifndef RAGNAROK_SOURCE_CLIENT_APPLICATIONMESSAGES_H
|
||||
#define RAGNAROK_SOURCE_CLIENT_APPLICATIONMESSAGES_H
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
struct TraditionalKeyInput;
|
||||
struct ServiceOptions;
|
||||
|
||||
namespace client {
|
||||
// Borrowed application globals. A non-null traditional input view denotes
|
||||
// CLanguageTC; base/TH/ARB virtual-key delivery is an established empty entry.
|
||||
struct ApplicationMessages {
|
||||
HWND& window;
|
||||
unsigned char& dragging;
|
||||
POINT& dragStart;
|
||||
RECT& dragRectangle;
|
||||
TraditionalKeyInput* const& traditional;
|
||||
ServiceOptions& service;
|
||||
|
||||
// Drains all messages (including WM_QUIT) through Translate/Dispatch, then
|
||||
// updates native window dragging. Does not invent the main window procedure.
|
||||
void Pump();
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,39 +0,0 @@
|
|||
#include "Client/ApplicationWindow.h"
|
||||
|
||||
namespace client {
|
||||
// OFFSET: 0x03DE9F37
|
||||
// FUNCTION: fn_45411
|
||||
HWND CreateApplicationWindow(
|
||||
DWORD extendedStyle,
|
||||
const char* className,
|
||||
const char*,
|
||||
DWORD style,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height,
|
||||
HWND parent,
|
||||
HMENU menu,
|
||||
HINSTANCE instance,
|
||||
void* parameter
|
||||
) {
|
||||
return CreateWindowExA(
|
||||
extendedStyle, className, "Ragnarok 2026", style | WS_SYSMENU, x, y, width, height, parent, menu, instance,
|
||||
parameter
|
||||
);
|
||||
}
|
||||
|
||||
// OFFSET: 0x00E57DD0
|
||||
// FUNCTION: fn_24360
|
||||
BOOL ClipApplicationCursor(HWND window) {
|
||||
RECT rectangle;
|
||||
GetClientRect(window, &rectangle);
|
||||
POINT first{rectangle.left, rectangle.top};
|
||||
POINT last{rectangle.right, rectangle.bottom};
|
||||
ClientToScreen(window, &first);
|
||||
ClientToScreen(window, &last);
|
||||
|
||||
RECT clip{first.x, first.y, last.x, last.y};
|
||||
return ClipCursor(&clip);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
#ifndef RAGNAROK_SOURCE_CLIENT_APPLICATIONWINDOW_H
|
||||
#define RAGNAROK_SOURCE_CLIENT_APPLICATIONWINDOW_H
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
namespace client {
|
||||
// Recovered CreateWindowExA wrapper, not the full application initializer.
|
||||
// Forces the title "Ragnarok 2026" and adds WS_SYSMENU to the caller's style.
|
||||
HWND CreateApplicationWindow(
|
||||
DWORD extendedStyle,
|
||||
const char* className,
|
||||
const char* ignoredTitle,
|
||||
DWORD style,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height,
|
||||
HWND parent,
|
||||
HMENU menu,
|
||||
HINSTANCE instance,
|
||||
void* parameter
|
||||
);
|
||||
|
||||
// Original global main-window handle is borrowed; clips its client rectangle
|
||||
// after converting both corners to screen coordinates. Returns ClipCursor.
|
||||
BOOL ClipApplicationCursor(HWND window);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
#include "Client/BrowserAddressBar.h"
|
||||
#include "Client/Browser/BrowserAddressBar.h"
|
||||
|
||||
#include <commctrl.h>
|
||||
|
||||
|
|
@ -6,7 +6,10 @@
|
|||
// FUNCTION: fn_17416
|
||||
bool BrowserAddressBar::Create(int width, int requestedHeight) {
|
||||
this->rebar = CreateWindowExA(
|
||||
0x80, "ReBarWindow32", "rebar", 0x56809648, 0, 0, width, 0, this->host, nullptr, GetModuleHandleA(nullptr), nullptr
|
||||
WS_EX_TOOLWINDOW, REBARCLASSNAMEA, "rebar",
|
||||
WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_BORDER | RBS_VARHEIGHT | RBS_BANDBORDERS | RBS_REGISTERDROP | RBS_DBLCLKTOGGLE |
|
||||
CCS_NOPARENTALIGN | CCS_NODIVIDER,
|
||||
0, 0, width, 0, this->host, nullptr, GetModuleHandleA(nullptr), nullptr
|
||||
);
|
||||
if (!this->rebar) {
|
||||
return false;
|
||||
|
|
@ -19,33 +22,31 @@ bool BrowserAddressBar::Create(int width, int requestedHeight) {
|
|||
}
|
||||
|
||||
HWND combo = CreateWindowExA(
|
||||
0x200, "COMBOBOX", "addressbar", 0x50000002, 10, 10, 160, 22, this->rebar, nullptr, GetModuleHandleA(nullptr),
|
||||
WS_EX_CLIENTEDGE, WC_COMBOBOXA, "addressbar", WS_CHILD | WS_VISIBLE | CBS_DROPDOWN, 10, 10, 160, 22, this->rebar, nullptr, GetModuleHandleA(nullptr),
|
||||
nullptr
|
||||
);
|
||||
|
||||
REBARBANDINFOA band{};
|
||||
band.cbSize = sizeof(band);
|
||||
band.fMask = 0xF1;
|
||||
band.fStyle = 0x24;
|
||||
band.fMask = RBBIM_STYLE | RBBIM_CHILD | RBBIM_CHILDSIZE | RBBIM_SIZE | RBBIM_BACKGROUND;
|
||||
band.fStyle = RBBS_CHILDEDGE | RBBS_FIXEDBMP;
|
||||
band.hwndChild = combo;
|
||||
band.cxMinChild = 0;
|
||||
band.cyMinChild = requestedHeight;
|
||||
band.cx = 160;
|
||||
band.hbmBack = LoadBitmapA(GetModuleHandleA(nullptr), nullptr);
|
||||
|
||||
if (!SendMessageA(this->rebar, RB_INSERTBANDA, static_cast<WPARAM>(-1), reinterpret_cast<LPARAM>(&band))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this->combo = combo;
|
||||
HWND edit = GetWindow(combo, GW_CHILD);
|
||||
this->previous =
|
||||
reinterpret_cast<WNDPROC>(SetWindowLongPtrA(edit, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(this->procedure)));
|
||||
this->previous = reinterpret_cast<WNDPROC>(SetWindowLongPtrA(edit, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(this->procedure)));
|
||||
|
||||
RECT rectangle;
|
||||
GetClientRect(this->host, &rectangle);
|
||||
SetWindowPos(
|
||||
this->rebar, nullptr, 0, 0, rectangle.right - rectangle.left, rectangle.bottom - rectangle.top, SWP_NOMOVE
|
||||
);
|
||||
SetWindowPos(this->rebar, nullptr, 0, 0, rectangle.right - rectangle.left, rectangle.bottom - rectangle.top, SWP_NOMOVE);
|
||||
ShowWindow(this->rebar, SW_HIDE);
|
||||
|
||||
this->height = 0;
|
||||
18
Source/Client/Browser/BrowserAddressBar.h
Normal file
18
Source/Client/Browser/BrowserAddressBar.h
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
#ifndef RAGNAROK_SOURCE_CLIENT_BROWSER_BROWSERADDRESSBAR_H
|
||||
#define RAGNAROK_SOURCE_CLIENT_BROWSER_BROWSERADDRESSBAR_H
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
struct BrowserAddressBar {
|
||||
HWND const& host;
|
||||
HWND& rebar;
|
||||
HWND& combo;
|
||||
int& height;
|
||||
const unsigned char& visible;
|
||||
WNDPROC& previous;
|
||||
WNDPROC procedure;
|
||||
|
||||
bool Create(int width, int height);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
#include "Client/BrowserAddressEdit.h"
|
||||
#include "Client/Browser/BrowserAddressEdit.h"
|
||||
#include "Client/Browser/BrowserMessages.h"
|
||||
|
||||
// OFFSET: 0x00AB21F0
|
||||
// FUNCTION: fn_17412
|
||||
|
|
@ -9,7 +10,7 @@ LRESULT BrowserAddressEdit::Message(HWND window, UINT message, WPARAM value, LPA
|
|||
}
|
||||
|
||||
if (message == WM_KEYDOWN && this->activeHost) {
|
||||
SendMessageA(*this->activeHost, WM_COMMAND, 1000, 0);
|
||||
SendMessageA(*this->activeHost, WM_COMMAND, static_cast<WPARAM>(BrowserCommand::Navigate), 0);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
13
Source/Client/Browser/BrowserAddressEdit.h
Normal file
13
Source/Client/Browser/BrowserAddressEdit.h
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
#ifndef RAGNAROK_SOURCE_CLIENT_BROWSER_BROWSERADDRESSEDIT_H
|
||||
#define RAGNAROK_SOURCE_CLIENT_BROWSER_BROWSERADDRESSEDIT_H
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
struct BrowserAddressEdit {
|
||||
WNDPROC const& previous;
|
||||
HWND const* const& activeHost;
|
||||
|
||||
LRESULT Message(HWND window, UINT message, WPARAM value, LPARAM flags);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -1,16 +1,10 @@
|
|||
#include "Client/BrowserClientSite.h"
|
||||
#include "Client/Browser/BrowserClientSite.h"
|
||||
|
||||
// OFFSET: 0x00AB1310
|
||||
// FUNCTION: fn_17334
|
||||
BrowserClientSite::BrowserClientSite(
|
||||
HWND window,
|
||||
IUnknown& browser,
|
||||
BrowserFactory& factory,
|
||||
const int& width,
|
||||
const int& height
|
||||
)
|
||||
: m_window(window), m_browser(&browser), m_events(*this, factory, width, height),
|
||||
m_inPlace(*this, this->m_window, this->m_browser), m_documentUI(*this), m_commands(*this) {
|
||||
BrowserClientSite::BrowserClientSite(HWND window, IUnknown& browser, BrowserFactory& factory, const int& width, const int& height)
|
||||
: m_window(window), m_browser(&browser), m_events(*this, factory, width, height), m_inPlace(*this, this->m_window, this->m_browser), m_documentUI(*this),
|
||||
m_commands(*this) {
|
||||
this->m_browser->AddRef();
|
||||
}
|
||||
|
||||
|
|
@ -40,8 +34,6 @@ HRESULT STDMETHODCALLTYPE BrowserClientSite::QueryInterface(REFIID iid, void** o
|
|||
} else if (iid == IID_IOleCommandTarget) {
|
||||
*output = static_cast<IOleCommandTarget*>(&this->m_commands);
|
||||
} else {
|
||||
// Unlike standard COM helpers, the original does not clear a failed output
|
||||
// and does not AddRef a successful result.
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
|
|
@ -1,16 +1,11 @@
|
|||
#ifndef RAGNAROK_SOURCE_CLIENT_BROWSERCLIENTSITE_H
|
||||
#define RAGNAROK_SOURCE_CLIENT_BROWSERCLIENTSITE_H
|
||||
#ifndef RAGNAROK_SOURCE_CLIENT_BROWSER_BROWSERCLIENTSITE_H
|
||||
#define RAGNAROK_SOURCE_CLIENT_BROWSER_BROWSERCLIENTSITE_H
|
||||
|
||||
#include "Client/BrowserCommandTarget.h"
|
||||
#include "Client/BrowserDocumentUI.h"
|
||||
#include "Client/BrowserInPlace.h"
|
||||
#include "UI/BrowserPopupDispatch.h"
|
||||
#include "Client/Browser/BrowserCommandTarget.h"
|
||||
#include "Client/Browser/BrowserDocumentUI.h"
|
||||
#include "Client/Browser/BrowserInPlace.h"
|
||||
#include "Client/Browser/BrowserPopupDispatch.h"
|
||||
|
||||
// Recovered site COM contracts with its owned popup-dispatch tear-off.
|
||||
// Factory and renderer dimensions must outlive the site. QueryInterface does
|
||||
// not acquire references; the containing browser controls this site's lifetime.
|
||||
// Retains the browser until destruction. COM reference calls return one;
|
||||
// lifetime is controlled by the containing CWebBrowser, not COM reference counts.
|
||||
class BrowserClientSite final : public IOleClientSite {
|
||||
public:
|
||||
BrowserClientSite(HWND window, IUnknown& browser, BrowserFactory& factory, const int& width, const int& height);
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
#include "Client/BrowserClose.h"
|
||||
#include "Client/Mouse.h"
|
||||
#include "Client/Browser/BrowserClose.h"
|
||||
#include "Client/Input/Mouse.h"
|
||||
|
||||
// OFFSET: 0x00AB24D0
|
||||
// FUNCTION: fn_45432
|
||||
21
Source/Client/Browser/BrowserClose.h
Normal file
21
Source/Client/Browser/BrowserClose.h
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
#ifndef RAGNAROK_SOURCE_CLIENT_BROWSER_BROWSERCLOSE_H
|
||||
#define RAGNAROK_SOURCE_CLIENT_BROWSER_BROWSERCLOSE_H
|
||||
|
||||
#include "Client/Browser/BrowserSiteAttachment.h"
|
||||
|
||||
class CMouse;
|
||||
|
||||
struct BrowserClose {
|
||||
BrowserSiteAttachment& attachment;
|
||||
IWebBrowser2*& browser;
|
||||
IUnknown*& externalEvents;
|
||||
HWND& host;
|
||||
HWND const& browserWindow;
|
||||
HWND const& applicationWindow;
|
||||
int& cursorState;
|
||||
CMouse& mouse;
|
||||
|
||||
bool Close();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -1,4 +1,6 @@
|
|||
#include "Client/BrowserCommandTarget.h"
|
||||
#include "Client/Browser/BrowserCommandTarget.h"
|
||||
|
||||
#include <mshtmhst.h>
|
||||
|
||||
// OFFSET: 0x00AB1A80
|
||||
// FUNCTION: fn_17379
|
||||
|
|
@ -21,7 +23,6 @@ ULONG STDMETHODCALLTYPE BrowserCommandTarget::Release() {
|
|||
// OFFSET: 0x00AB1C50
|
||||
// FUNCTION: fn_17385
|
||||
HRESULT STDMETHODCALLTYPE BrowserCommandTarget::QueryStatus(const GUID*, ULONG, OLECMD[], OLECMDTEXT*) {
|
||||
// The original reports success without reading or publishing command flags.
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
|
@ -29,15 +30,11 @@ HRESULT STDMETHODCALLTYPE BrowserCommandTarget::QueryStatus(const GUID*, ULONG,
|
|||
// FUNCTION: fn_17353
|
||||
HRESULT STDMETHODCALLTYPE BrowserCommandTarget::Exec(const GUID* group, DWORD command, DWORD, VARIANT*, VARIANT*) {
|
||||
// STATIC: 0x011B0880 (CGID_DocHostCommandHandler)
|
||||
static constexpr GUID documentHostCommands = {
|
||||
0xF38BC242, 0xB950, 0x11D1, {0x89, 0x18, 0x00, 0xC0, 0x4F, 0xC2, 0xC8, 0x36}
|
||||
};
|
||||
|
||||
if (!group || !IsEqualGUID(*group, documentHostCommands)) {
|
||||
if (!group || !IsEqualGUID(*group, CGID_DocHostCommandHandler)) {
|
||||
return OLECMDERR_E_UNKNOWNGROUP;
|
||||
}
|
||||
|
||||
if (command == 40 || command == 41) {
|
||||
if (command == OLECMDID_SHOWSCRIPTERROR || command == OLECMDID_SHOWMESSAGE) {
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
|
@ -1,15 +1,10 @@
|
|||
#ifndef RAGNAROK_SOURCE_CLIENT_BROWSERCOMMANDTARGET_H
|
||||
#define RAGNAROK_SOURCE_CLIENT_BROWSERCOMMANDTARGET_H
|
||||
#ifndef RAGNAROK_SOURCE_CLIENT_BROWSER_BROWSERCOMMANDTARGET_H
|
||||
#define RAGNAROK_SOURCE_CLIENT_BROWSER_BROWSERCOMMANDTARGET_H
|
||||
|
||||
// clang-format off
|
||||
#include <windows.h>
|
||||
#include <ole2.h>
|
||||
#include <docobj.h>
|
||||
// clang-format on
|
||||
|
||||
// CWebBrowser's site owns this tear-off interface.
|
||||
// Identity delegates to that site; AddRef/Release deliberately return one.
|
||||
// The caller must keep the site alive for this interface's entire lifetime.
|
||||
class BrowserCommandTarget final : public IOleCommandTarget {
|
||||
public:
|
||||
explicit BrowserCommandTarget(IUnknown& site) : m_site(site) {
|
||||
|
|
@ -19,8 +14,7 @@ public:
|
|||
ULONG STDMETHODCALLTYPE AddRef() override;
|
||||
ULONG STDMETHODCALLTYPE Release() override;
|
||||
HRESULT STDMETHODCALLTYPE QueryStatus(const GUID* group, ULONG count, OLECMD commands[], OLECMDTEXT* text) override;
|
||||
HRESULT STDMETHODCALLTYPE
|
||||
Exec(const GUID* group, DWORD command, DWORD options, VARIANT* input, VARIANT* output) override;
|
||||
HRESULT STDMETHODCALLTYPE Exec(const GUID* group, DWORD command, DWORD options, VARIANT* input, VARIANT* output) override;
|
||||
|
||||
private:
|
||||
IUnknown& m_site;
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
#include "Client/BrowserCreation.h"
|
||||
#include "Client/BrowserInterface.h"
|
||||
#include "Client/Browser/BrowserCreation.h"
|
||||
#include "Client/Browser/BrowserInterface.h"
|
||||
|
||||
// OFFSET: 0x00AB22B0
|
||||
// FUNCTION: fn_17413
|
||||
18
Source/Client/Browser/BrowserCreation.h
Normal file
18
Source/Client/Browser/BrowserCreation.h
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
#ifndef RAGNAROK_SOURCE_CLIENT_BROWSER_BROWSERCREATION_H
|
||||
#define RAGNAROK_SOURCE_CLIENT_BROWSER_BROWSERCREATION_H
|
||||
|
||||
#include "Client/Browser/BrowserAddressBar.h"
|
||||
#include "Client/Browser/BrowserHostWindow.h"
|
||||
#include "Client/Browser/BrowserSiteAttachment.h"
|
||||
|
||||
struct BrowserCreation {
|
||||
IWebBrowser2*& browser;
|
||||
HWND& browserWindow;
|
||||
BrowserHostWindow& window;
|
||||
BrowserSiteAttachment& attachment;
|
||||
BrowserAddressBar& addressBar;
|
||||
|
||||
bool Create(HWND parent, HINSTANCE instance, int width, int height);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
#include "Client/BrowserCursor.h"
|
||||
#include "Client/Mouse.h"
|
||||
#include "Client/Browser/BrowserCursor.h"
|
||||
#include "Client/Input/Mouse.h"
|
||||
#include "Render/RenderSystemBase.h"
|
||||
|
||||
// OFFSET: 0x00AB32E0
|
||||
|
|
@ -10,9 +10,8 @@ void BrowserCursor::Set(int value) {
|
|||
}
|
||||
|
||||
if (value != 0) {
|
||||
SetCursor(LoadCursorA(nullptr, MAKEINTRESOURCEA(32512)));
|
||||
// Original mouse centering queries Width then Height before replacing
|
||||
// both coordinates with -100. Retain these virtual calls and their order.
|
||||
SetCursor(LoadCursorA(nullptr, reinterpret_cast<LPCSTR>(IDC_ARROW)));
|
||||
|
||||
this->mouse.SetX(static_cast<int>(this->renderSystem.Width()) / 2);
|
||||
this->mouse.SetY(static_cast<int>(this->renderSystem.Height()) / 2);
|
||||
this->mouse.SetX(-100);
|
||||
19
Source/Client/Browser/BrowserCursor.h
Normal file
19
Source/Client/Browser/BrowserCursor.h
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
#ifndef RAGNAROK_SOURCE_CLIENT_BROWSER_BROWSERCURSOR_H
|
||||
#define RAGNAROK_SOURCE_CLIENT_BROWSER_BROWSERCURSOR_H
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
class CMouse;
|
||||
class CRenderSystemBase;
|
||||
|
||||
struct BrowserCursor {
|
||||
int& state;
|
||||
CMouse& mouse;
|
||||
CRenderSystemBase& renderSystem;
|
||||
HWND const& applicationWindow;
|
||||
|
||||
void Set(int value);
|
||||
void Poll();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
#include "Client/BrowserDocumentUI.h"
|
||||
#include "Client/Browser/BrowserDocumentUI.h"
|
||||
|
||||
// OFFSET: 0x00AB1AC0
|
||||
// FUNCTION: fn_17381
|
||||
|
|
@ -27,23 +27,16 @@ HRESULT STDMETHODCALLTYPE BrowserDocumentUI::ShowContextMenu(DWORD, POINT*, IUnk
|
|||
// OFFSET: 0x00AB1770
|
||||
// FUNCTION: fn_17359
|
||||
HRESULT STDMETHODCALLTYPE BrowserDocumentUI::GetHostInfo(DOCHOSTUIINFO* info) {
|
||||
// Original x86 cbSize, even when compiling for a wider host. The two optional
|
||||
// string pointers are not initialized by this operation.
|
||||
info->cbSize = 20;
|
||||
info->dwFlags = 4;
|
||||
info->dwDoubleClick = 0;
|
||||
info->cbSize = sizeof(*info);
|
||||
info->dwFlags = DOCHOSTUIFLAG_NO3DBORDER;
|
||||
info->dwDoubleClick = DOCHOSTUIDBLCLK_DEFAULT;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
// OFFSET: 0x00AB1D80
|
||||
// FUNCTION: fn_17404
|
||||
HRESULT STDMETHODCALLTYPE BrowserDocumentUI::ShowUI(
|
||||
DWORD,
|
||||
IOleInPlaceActiveObject*,
|
||||
IOleCommandTarget*,
|
||||
IOleInPlaceFrame*,
|
||||
IOleInPlaceUIWindow*
|
||||
) {
|
||||
HRESULT STDMETHODCALLTYPE BrowserDocumentUI::ShowUI(DWORD, IOleInPlaceActiveObject*, IOleCommandTarget*, IOleInPlaceFrame*, IOleInPlaceUIWindow*) {
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
|
@ -1,14 +1,10 @@
|
|||
#ifndef RAGNAROK_SOURCE_CLIENT_BROWSERDOCUMENTUI_H
|
||||
#define RAGNAROK_SOURCE_CLIENT_BROWSERDOCUMENTUI_H
|
||||
#ifndef RAGNAROK_SOURCE_CLIENT_BROWSER_BROWSERDOCUMENTUI_H
|
||||
#define RAGNAROK_SOURCE_CLIENT_BROWSER_BROWSERDOCUMENTUI_H
|
||||
|
||||
// clang-format off
|
||||
#include <windows.h>
|
||||
#include <ole2.h>
|
||||
#include <mshtmhst.h>
|
||||
// clang-format on
|
||||
|
||||
// Site-owned IDocHostUIHandler tear-off. Identity delegates to the borrowed
|
||||
// site; reference calls do not manage lifetime. Unwritten outputs stay unwritten.
|
||||
class BrowserDocumentUI final : public IDocHostUIHandler {
|
||||
public:
|
||||
explicit BrowserDocumentUI(IUnknown& site) : m_site(site) {
|
||||
|
|
@ -19,13 +15,8 @@ public:
|
|||
ULONG STDMETHODCALLTYPE Release() override;
|
||||
HRESULT STDMETHODCALLTYPE ShowContextMenu(DWORD id, POINT* point, IUnknown* reserved, IDispatch* dispatch) override;
|
||||
HRESULT STDMETHODCALLTYPE GetHostInfo(DOCHOSTUIINFO* info) override;
|
||||
HRESULT STDMETHODCALLTYPE ShowUI(
|
||||
DWORD id,
|
||||
IOleInPlaceActiveObject* active,
|
||||
IOleCommandTarget* commands,
|
||||
IOleInPlaceFrame* frame,
|
||||
IOleInPlaceUIWindow* document
|
||||
) override;
|
||||
HRESULT STDMETHODCALLTYPE
|
||||
ShowUI(DWORD id, IOleInPlaceActiveObject* active, IOleCommandTarget* commands, IOleInPlaceFrame* frame, IOleInPlaceUIWindow* document) override;
|
||||
HRESULT STDMETHODCALLTYPE HideUI() override;
|
||||
HRESULT STDMETHODCALLTYPE UpdateUI() override;
|
||||
HRESULT STDMETHODCALLTYPE EnableModeless(BOOL enable) override;
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
#include "Client/BrowserRegistry.h"
|
||||
#include "Client/WebBrowser.h"
|
||||
#include "Client/Browser/BrowserRegistry.h"
|
||||
#include "Client/Browser/WebBrowser.h"
|
||||
#include "Contents/MessageTable.h"
|
||||
#include "UI/BrowserFactory.h"
|
||||
#include "UI/ChatNotifications.h"
|
||||
#include "Client/Browser/BrowserFactory.h"
|
||||
#include "UI/Chat/ChatNotifications.h"
|
||||
|
||||
#include <new>
|
||||
|
||||
|
|
@ -13,6 +13,7 @@ CWebBrowser* BrowserFactory::Create(int width, int height) {
|
|||
this->notifications.Refresh();
|
||||
const char* message = LookupMessage(1578, this->languagePrefix, this->serviceType, this->language);
|
||||
this->notifications.Text(message, 255, nullptr, 0, false);
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
#ifndef RAGNAROK_SOURCE_UI_BROWSERFACTORY_H
|
||||
#define RAGNAROK_SOURCE_UI_BROWSERFACTORY_H
|
||||
#ifndef RAGNAROK_SOURCE_CLIENT_BROWSER_BROWSERFACTORY_H
|
||||
#define RAGNAROK_SOURCE_CLIENT_BROWSER_BROWSERFACTORY_H
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
|
|
@ -8,9 +8,6 @@ struct WebBrowserContext;
|
|||
struct BrowserRegistry;
|
||||
struct ChatNotifications;
|
||||
|
||||
// Ordinary browser creation is distinct from the special-browser factory.
|
||||
// The limit counts all map nodes, not nonnull entries. Failed ordinary creation
|
||||
// retains the allocated browser in the original; it is not published or deleted.
|
||||
struct BrowserFactory {
|
||||
BrowserRegistry& registry;
|
||||
WebBrowserContext& context;
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
#include "Client/BrowserFrame.h"
|
||||
#include "Client/Browser/BrowserFrame.h"
|
||||
|
||||
// OFFSET: 0x00AB2610
|
||||
// FUNCTION: fn_17414
|
||||
|
|
@ -9,10 +9,7 @@ void BrowserFrame::Normalize() {
|
|||
|
||||
RECT rectangle;
|
||||
GetWindowRect(this->browserWindow, &rectangle);
|
||||
if (
|
||||
rectangle.right - rectangle.left != this->sizing.screenWidth ||
|
||||
rectangle.bottom - rectangle.top != this->sizing.screenHeight
|
||||
) {
|
||||
if (rectangle.right - rectangle.left != this->sizing.screenWidth || rectangle.bottom - rectangle.top != this->sizing.screenHeight) {
|
||||
return;
|
||||
}
|
||||
|
||||
18
Source/Client/Browser/BrowserFrame.h
Normal file
18
Source/Client/Browser/BrowserFrame.h
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
#ifndef RAGNAROK_SOURCE_CLIENT_BROWSER_BROWSERFRAME_H
|
||||
#define RAGNAROK_SOURCE_CLIENT_BROWSER_BROWSERFRAME_H
|
||||
|
||||
#include "Client/Browser/BrowserCursor.h"
|
||||
#include "Client/Browser/BrowserWindowSizing.h"
|
||||
|
||||
struct BrowserFrame {
|
||||
BrowserWindowSizing& sizing;
|
||||
BrowserCursor& cursor;
|
||||
HWND const& host;
|
||||
HWND const& browserWindow;
|
||||
const bool& hasExternalEvents;
|
||||
|
||||
void Normalize();
|
||||
void Poll();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
#include "Client/BrowserHostWindow.h"
|
||||
#include "Client/Browser/BrowserHostWindow.h"
|
||||
|
||||
// OFFSET: 0x00AB29D0
|
||||
// FUNCTION: fn_45435
|
||||
|
|
@ -11,10 +11,7 @@ bool BrowserHostWindow::Create(HWND parent, HINSTANCE instance, int width, int h
|
|||
windowClass.lpszClassName = "ROWebBrowser";
|
||||
RegisterClassExA(&windowClass);
|
||||
|
||||
this->host = CreateWindowExA(
|
||||
0, "ROWebBrowser", this->title, WS_POPUP | WS_OVERLAPPEDWINDOW, 0, 0, width, height, parent, nullptr, instance,
|
||||
nullptr
|
||||
);
|
||||
this->host = CreateWindowExA(0, "ROWebBrowser", this->title, WS_POPUP | WS_OVERLAPPEDWINDOW, 0, 0, width, height, parent, nullptr, instance, nullptr);
|
||||
if (!this->host) {
|
||||
OutputDebugStringA("failed : CreateWindow() \n");
|
||||
return false;
|
||||
|
|
@ -23,5 +20,6 @@ bool BrowserHostWindow::Create(HWND parent, HINSTANCE instance, int width, int h
|
|||
UpdateWindow(this->host);
|
||||
SetParent(this->browser, this->host);
|
||||
SetWindowLongA(this->browser, GWL_STYLE, WS_CHILD);
|
||||
|
||||
return true;
|
||||
}
|
||||
15
Source/Client/Browser/BrowserHostWindow.h
Normal file
15
Source/Client/Browser/BrowserHostWindow.h
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
#ifndef RAGNAROK_SOURCE_CLIENT_BROWSER_BROWSERHOSTWINDOW_H
|
||||
#define RAGNAROK_SOURCE_CLIENT_BROWSER_BROWSERHOSTWINDOW_H
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
struct BrowserHostWindow {
|
||||
HWND& host;
|
||||
HWND const& browser;
|
||||
const char* const& title;
|
||||
WNDPROC procedure;
|
||||
|
||||
bool Create(HWND parent, HINSTANCE instance, int width, int height);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
#include "Client/BrowserInPlace.h"
|
||||
#include "Client/Browser/BrowserInPlace.h"
|
||||
|
||||
// OFFSET: 0x00AB1AE0
|
||||
// FUNCTION: fn_17382
|
||||
|
|
@ -142,19 +142,15 @@ HRESULT STDMETHODCALLTYPE BrowserInPlaceSite::OnUIActivate() {
|
|||
|
||||
// OFFSET: 0x00AB1820
|
||||
// FUNCTION: fn_17367
|
||||
HRESULT STDMETHODCALLTYPE BrowserInPlaceSite::GetWindowContext(
|
||||
IOleInPlaceFrame** frame,
|
||||
IOleInPlaceUIWindow** document,
|
||||
RECT*,
|
||||
RECT*,
|
||||
OLEINPLACEFRAMEINFO* info
|
||||
) {
|
||||
HRESULT STDMETHODCALLTYPE
|
||||
BrowserInPlaceSite::GetWindowContext(IOleInPlaceFrame** frame, IOleInPlaceUIWindow** document, RECT*, RECT*, OLEINPLACEFRAMEINFO* info) {
|
||||
*frame = &this->m_frame;
|
||||
*document = nullptr;
|
||||
info->fMDIApp = FALSE;
|
||||
info->hwndFrame = this->m_window;
|
||||
info->haccel = nullptr;
|
||||
info->cAccelEntries = 0;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
|
@ -191,8 +187,6 @@ HRESULT STDMETHODCALLTYPE BrowserInPlaceSite::DeactivateAndUndo() {
|
|||
// OFFSET: 0x00AB19F0
|
||||
// FUNCTION: fn_17375
|
||||
HRESULT STDMETHODCALLTYPE BrowserInPlaceSite::OnPosRectChange(const RECT* position) {
|
||||
// The original requires an attached browser and retains this IOleObject
|
||||
// reference, including when its subsequent in-place QueryInterface fails.
|
||||
IOleObject* object;
|
||||
HRESULT result = this->m_browser->QueryInterface(IID_IOleObject, reinterpret_cast<void**>(&object));
|
||||
if (SUCCEEDED(result)) {
|
||||
|
|
@ -1,13 +1,9 @@
|
|||
#ifndef RAGNAROK_SOURCE_CLIENT_BROWSERINPLACE_H
|
||||
#define RAGNAROK_SOURCE_CLIENT_BROWSERINPLACE_H
|
||||
#ifndef RAGNAROK_SOURCE_CLIENT_BROWSER_BROWSERINPLACE_H
|
||||
#define RAGNAROK_SOURCE_CLIENT_BROWSER_BROWSERINPLACE_H
|
||||
|
||||
// clang-format off
|
||||
#include <windows.h>
|
||||
#include <ole2.h>
|
||||
// clang-format on
|
||||
|
||||
// Site-owned tear-offs: borrowed identity, HWND and browser, with fixed-one
|
||||
// reference counts. These interfaces do not own or extend the site's lifetime.
|
||||
class BrowserInPlaceFrame final : public IOleInPlaceFrame {
|
||||
public:
|
||||
BrowserInPlaceFrame(IUnknown& site, HWND const& window) : m_site(site), m_window(window) {
|
||||
|
|
@ -36,8 +32,7 @@ private:
|
|||
|
||||
class BrowserInPlaceSite final : public IOleInPlaceSite {
|
||||
public:
|
||||
BrowserInPlaceSite(IUnknown& site, HWND const& window, IUnknown* const& browser)
|
||||
: m_site(site), m_window(window), m_browser(browser), m_frame(site, window) {
|
||||
BrowserInPlaceSite(IUnknown& site, HWND const& window, IUnknown* const& browser) : m_site(site), m_window(window), m_browser(browser), m_frame(site, window) {
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void** output) override;
|
||||
|
|
@ -48,13 +43,8 @@ public:
|
|||
HRESULT STDMETHODCALLTYPE CanInPlaceActivate() override;
|
||||
HRESULT STDMETHODCALLTYPE OnInPlaceActivate() override;
|
||||
HRESULT STDMETHODCALLTYPE OnUIActivate() override;
|
||||
HRESULT STDMETHODCALLTYPE GetWindowContext(
|
||||
IOleInPlaceFrame** frame,
|
||||
IOleInPlaceUIWindow** document,
|
||||
RECT* position,
|
||||
RECT* clip,
|
||||
OLEINPLACEFRAMEINFO* info
|
||||
) override;
|
||||
HRESULT STDMETHODCALLTYPE
|
||||
GetWindowContext(IOleInPlaceFrame** frame, IOleInPlaceUIWindow** document, RECT* position, RECT* clip, OLEINPLACEFRAMEINFO* info) override;
|
||||
HRESULT STDMETHODCALLTYPE Scroll(SIZE extent) override;
|
||||
HRESULT STDMETHODCALLTYPE OnUIDeactivate(BOOL undoable) override;
|
||||
HRESULT STDMETHODCALLTYPE OnInPlaceDeactivate() override;
|
||||
|
|
@ -1,17 +1,17 @@
|
|||
#include "Client/ApplicationActivation.h"
|
||||
#include "Client/BrowserInputHandoff.h"
|
||||
#include "Client/Mouse.h"
|
||||
#include "Contents/ServiceOptions.h"
|
||||
#include "Client/Application/ApplicationActivation.h"
|
||||
#include "Client/Browser/BrowserInputHandoff.h"
|
||||
#include "Client/Input/Mouse.h"
|
||||
#include "Contents/Configuration/ServiceOptions.h"
|
||||
|
||||
// OFFSET: 0x00AB2720
|
||||
// FUNCTION: fn_45433
|
||||
void BrowserInputHandoff::Enter() {
|
||||
if (this->service.Get(271) == 0) {
|
||||
if (this->service.Get(ServiceOption::ConfineCursor) == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
POINT position{this->mouse.x, this->mouse.y};
|
||||
this->service.Set(271, 0);
|
||||
this->service.Set(ServiceOption::ConfineCursor, 0);
|
||||
this->mouse.SetX(position.x);
|
||||
this->mouse.SetY(position.y);
|
||||
this->restoreOption = 1;
|
||||
|
|
@ -29,7 +29,7 @@ void BrowserInputHandoff::Restore() {
|
|||
POINT position;
|
||||
GetCursorPos(&position);
|
||||
ScreenToClient(this->applicationWindow, &position);
|
||||
this->service.Set(271, 1);
|
||||
this->service.Set(ServiceOption::ConfineCursor, 1);
|
||||
this->mouse.SetX(position.x);
|
||||
this->mouse.SetY(position.y);
|
||||
SetActiveWindow(this->applicationWindow);
|
||||
21
Source/Client/Browser/BrowserInputHandoff.h
Normal file
21
Source/Client/Browser/BrowserInputHandoff.h
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
#ifndef RAGNAROK_SOURCE_CLIENT_BROWSER_BROWSERINPUTHANDOFF_H
|
||||
#define RAGNAROK_SOURCE_CLIENT_BROWSER_BROWSERINPUTHANDOFF_H
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
class CMouse;
|
||||
struct ServiceOptions;
|
||||
struct ApplicationActivation;
|
||||
|
||||
struct BrowserInputHandoff {
|
||||
unsigned char& restoreOption;
|
||||
HWND const& applicationWindow;
|
||||
ServiceOptions& service;
|
||||
CMouse& mouse;
|
||||
ApplicationActivation& activation;
|
||||
|
||||
void Enter();
|
||||
void Restore();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
#include "Client/BrowserInterface.h"
|
||||
#include "Client/Browser/BrowserInterface.h"
|
||||
|
||||
#include <memory>
|
||||
#include <ocidl.h>
|
||||
|
|
@ -6,19 +6,17 @@
|
|||
// OFFSET: 0x00AB2CD0
|
||||
// FUNCTION: fn_45437
|
||||
bool CreateBrowserInterface(IWebBrowser2*& browser, HWND& window) {
|
||||
const HRESULT result = CoCreateInstance(
|
||||
CLSID_WebBrowser, nullptr, CLSCTX_INPROC_SERVER | CLSCTX_INPROC_HANDLER, IID_IWebBrowser2,
|
||||
reinterpret_cast<void**>(&browser)
|
||||
);
|
||||
const HRESULT result =
|
||||
CoCreateInstance(CLSID_WebBrowser, nullptr, CLSCTX_INPROC_SERVER | CLSCTX_INPROC_HANDLER, IID_IWebBrowser2, reinterpret_cast<void**>(&browser));
|
||||
|
||||
if (FAILED(result)) {
|
||||
OutputDebugStringA("error : MakeWebBrowserInterface_InProc FAILED \n");
|
||||
HLOCAL message = nullptr;
|
||||
FormatMessageA(
|
||||
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM, nullptr,
|
||||
GetLastError(), 0, reinterpret_cast<char*>(&message), 0, nullptr
|
||||
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM, nullptr, GetLastError(), 0,
|
||||
reinterpret_cast<char*>(&message), 0, nullptr
|
||||
);
|
||||
// The reference locks and reports this buffer without freeing it.
|
||||
|
||||
OutputDebugStringA(static_cast<const char*>(LocalLock(message)));
|
||||
return false;
|
||||
}
|
||||
|
|
@ -33,18 +31,17 @@ bool CreateBrowserInterface(IWebBrowser2*& browser, HWND& window) {
|
|||
// OFFSET: 0x00AB2C10
|
||||
// FUNCTION: fn_45436
|
||||
bool CreateExternalBrowserInterface(IWebBrowser2*& browser, HWND& window, HWND const& host) {
|
||||
const HRESULT result = CoCreateInstance(
|
||||
CLSID_InternetExplorer, nullptr, CLSCTX_LOCAL_SERVER, IID_IWebBrowser2, reinterpret_cast<void**>(&browser)
|
||||
);
|
||||
const HRESULT result = CoCreateInstance(CLSID_InternetExplorer, nullptr, CLSCTX_LOCAL_SERVER, IID_IWebBrowser2, reinterpret_cast<void**>(&browser));
|
||||
|
||||
if (FAILED(result)) {
|
||||
OutputDebugStringA("error : MakeWebBrowserInterface FAILED \n");
|
||||
HLOCAL message = nullptr;
|
||||
FormatMessageA(
|
||||
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM, nullptr,
|
||||
GetLastError(), 0, reinterpret_cast<char*>(&message), 0, nullptr
|
||||
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM, nullptr, GetLastError(), 0,
|
||||
reinterpret_cast<char*>(&message), 0, nullptr
|
||||
);
|
||||
OutputDebugStringA(static_cast<const char*>(LocalLock(message)));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -103,6 +100,7 @@ HRESULT AdviseBrowserEvents(IUnknown* source, IUnknown* sink, REFIID events, DWO
|
|||
IConnectionPointContainer* container = nullptr;
|
||||
IConnectionPoint* point = nullptr;
|
||||
HRESULT result = source->QueryInterface(IID_IConnectionPointContainer, reinterpret_cast<void**>(&container));
|
||||
|
||||
if (SUCCEEDED(result)) {
|
||||
result = container->FindConnectionPoint(events, &point);
|
||||
if (SUCCEEDED(result)) {
|
||||
|
|
@ -113,9 +111,11 @@ HRESULT AdviseBrowserEvents(IUnknown* source, IUnknown* sink, REFIID events, DWO
|
|||
if (point) {
|
||||
point->Release();
|
||||
}
|
||||
|
||||
if (container) {
|
||||
container->Release();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
@ -129,6 +129,7 @@ HRESULT UnadviseBrowserEvents(IUnknown* source, REFIID events, DWORD cookie) {
|
|||
IConnectionPointContainer* container = nullptr;
|
||||
IConnectionPoint* point = nullptr;
|
||||
HRESULT result = source->QueryInterface(IID_IConnectionPointContainer, reinterpret_cast<void**>(&container));
|
||||
|
||||
if (SUCCEEDED(result)) {
|
||||
result = container->FindConnectionPoint(events, &point);
|
||||
if (SUCCEEDED(result)) {
|
||||
|
|
@ -139,8 +140,10 @@ HRESULT UnadviseBrowserEvents(IUnknown* source, REFIID events, DWORD cookie) {
|
|||
if (point) {
|
||||
point->Release();
|
||||
}
|
||||
|
||||
if (container) {
|
||||
container->Release();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
19
Source/Client/Browser/BrowserInterface.h
Normal file
19
Source/Client/Browser/BrowserInterface.h
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
#ifndef RAGNAROK_SOURCE_CLIENT_BROWSER_BROWSERINTERFACE_H
|
||||
#define RAGNAROK_SOURCE_CLIENT_BROWSER_BROWSERINTERFACE_H
|
||||
|
||||
#include <windows.h>
|
||||
#include <ole2.h>
|
||||
#include <exdisp.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
bool CreateBrowserInterface(IWebBrowser2*& browser, HWND& window);
|
||||
|
||||
bool CreateExternalBrowserInterface(IWebBrowser2*& browser, HWND& window, HWND const& host);
|
||||
|
||||
bool NavigateBrowser(IWebBrowser2* const& browser, HWND const& host, HWND const& title, std::string address);
|
||||
|
||||
HRESULT AdviseBrowserEvents(IUnknown* source, IUnknown* sink, REFIID events, DWORD* cookie);
|
||||
HRESULT UnadviseBrowserEvents(IUnknown* source, REFIID events, DWORD cookie);
|
||||
|
||||
#endif
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
#include "Client/BrowserMessages.h"
|
||||
#include "Client/BrowserRegistry.h"
|
||||
#include "Client/WebBrowser.h"
|
||||
#include "Client/Browser/BrowserMessages.h"
|
||||
#include "Client/Browser/BrowserRegistry.h"
|
||||
#include "Client/Browser/WebBrowser.h"
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
|
|
@ -36,7 +36,7 @@ LRESULT BrowserMessages::Message(HWND window, UINT message, WPARAM value, LPARAM
|
|||
}
|
||||
break;
|
||||
case WM_COMMAND:
|
||||
if (static_cast<std::uint16_t>(value) == 1000 && browser) {
|
||||
if (LOWORD(value) == static_cast<WORD>(BrowserCommand::Navigate) && browser) {
|
||||
char address[512];
|
||||
GetWindowTextA(browser->combo, address, sizeof(address));
|
||||
browser->Navigate(address);
|
||||
|
|
@ -1,13 +1,13 @@
|
|||
#ifndef RAGNAROK_SOURCE_CLIENT_BROWSERMESSAGES_H
|
||||
#define RAGNAROK_SOURCE_CLIENT_BROWSERMESSAGES_H
|
||||
#ifndef RAGNAROK_SOURCE_CLIENT_BROWSER_BROWSERMESSAGES_H
|
||||
#define RAGNAROK_SOURCE_CLIENT_BROWSER_BROWSERMESSAGES_H
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
class CWebBrowser;
|
||||
struct BrowserRegistry;
|
||||
|
||||
// Borrowed UIWindowMgr browser registry, active browser and main HWND.
|
||||
// Caller installs its native thunk; this implements the entire original body.
|
||||
enum class BrowserCommand : WORD { Navigate = 1000 };
|
||||
|
||||
struct BrowserMessages {
|
||||
BrowserRegistry& registry;
|
||||
CWebBrowser*& active;
|
||||
|
|
@ -1,10 +1,11 @@
|
|||
#include "Client/WebBrowser.h"
|
||||
#include "UI/BrowserFactory.h"
|
||||
#include "UI/BrowserPopupDispatch.h"
|
||||
#include "Client/Browser/WebBrowser.h"
|
||||
#include "Client/Browser/BrowserFactory.h"
|
||||
#include "Client/Browser/BrowserPopupDispatch.h"
|
||||
|
||||
#include "Utility/Math/ScalarConversion.h"
|
||||
#include <exdispid.h>
|
||||
#include <cwchar>
|
||||
#include <memory>
|
||||
#include <xmmintrin.h>
|
||||
|
||||
// OFFSET: 0x00AB1AA0
|
||||
// FUNCTION: fn_17380
|
||||
|
|
@ -44,23 +45,22 @@ HRESULT STDMETHODCALLTYPE BrowserPopupDispatch::GetIDsOfNames(REFIID, LPOLESTR*,
|
|||
|
||||
// OFFSET: 0x00AB1880
|
||||
// FUNCTION: fn_17370
|
||||
HRESULT STDMETHODCALLTYPE
|
||||
BrowserPopupDispatch::Invoke(DISPID id, REFIID, LCID, WORD, DISPPARAMS* args, VARIANT*, EXCEPINFO*, UINT*) {
|
||||
if (id != 273) {
|
||||
HRESULT STDMETHODCALLTYPE BrowserPopupDispatch::Invoke(DISPID id, REFIID, LCID, WORD, DISPPARAMS* args, VARIANT*, EXCEPINFO*, UINT*) {
|
||||
if (id != DISPID_NEWWINDOW3) {
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
const wchar_t* url = args->rgvarg[0].bstrVal;
|
||||
// Original writes literal 11 through Cancel's by-reference boolean. Preserve
|
||||
// that noncanonical true value, and write it before the factory callback.
|
||||
|
||||
*args->rgvarg[3].pboolVal = 11;
|
||||
|
||||
// STATIC: 0x01115448
|
||||
// GLOBAL: gl_13426
|
||||
const __m128 scale = _mm_set_ss(0.7f);
|
||||
const int height = _mm_cvtt_ss2si(_mm_mul_ss(_mm_cvtsi32_ss(_mm_setzero_ps(), this->m_height), scale));
|
||||
const int width = _mm_cvtt_ss2si(_mm_mul_ss(_mm_cvtsi32_ss(_mm_setzero_ps(), this->m_width), scale));
|
||||
const float scale = 0.7f;
|
||||
const int height = TruncateToInt(static_cast<float>(this->m_height) * scale);
|
||||
const int width = TruncateToInt(static_cast<float>(this->m_width) * scale);
|
||||
CWebBrowser* browser = this->m_factory.Create(width, height);
|
||||
|
||||
if (!browser) {
|
||||
return S_OK;
|
||||
}
|
||||
|
|
@ -70,5 +70,6 @@ BrowserPopupDispatch::Invoke(DISPID id, REFIID, LCID, WORD, DISPPARAMS* args, VA
|
|||
WideCharToMultiByte(CP_ACP, 0, url, -1, converted.get(), static_cast<int>(length), nullptr, nullptr);
|
||||
converted[length] = '\0';
|
||||
browser->Navigate(converted.get());
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
|
@ -1,16 +1,11 @@
|
|||
#ifndef RAGNAROK_SOURCE_UI_BROWSERPOPUPDISPATCH_H
|
||||
#define RAGNAROK_SOURCE_UI_BROWSERPOPUPDISPATCH_H
|
||||
#ifndef RAGNAROK_SOURCE_CLIENT_BROWSER_BROWSERPOPUPDISPATCH_H
|
||||
#define RAGNAROK_SOURCE_CLIENT_BROWSER_BROWSERPOPUPDISPATCH_H
|
||||
|
||||
// clang-format off
|
||||
#include <windows.h>
|
||||
#include <ole2.h>
|
||||
// clang-format on
|
||||
|
||||
struct BrowserFactory;
|
||||
|
||||
// Site-owned dispatch tear-off. Identity and renderer dimensions are borrowed.
|
||||
// Fixed-one reference methods match the other site tear-offs, not
|
||||
// CWebEventReceiver's independently reference-counted lifetime.
|
||||
class BrowserPopupDispatch final : public IDispatch {
|
||||
public:
|
||||
BrowserPopupDispatch(IUnknown& site, BrowserFactory& factory, const int& width, const int& height)
|
||||
|
|
@ -23,16 +18,8 @@ public:
|
|||
HRESULT STDMETHODCALLTYPE GetTypeInfoCount(UINT* count) override;
|
||||
HRESULT STDMETHODCALLTYPE GetTypeInfo(UINT index, LCID locale, ITypeInfo** output) override;
|
||||
HRESULT STDMETHODCALLTYPE GetIDsOfNames(REFIID iid, LPOLESTR* names, UINT count, LCID locale, DISPID* ids) override;
|
||||
HRESULT STDMETHODCALLTYPE Invoke(
|
||||
DISPID id,
|
||||
REFIID iid,
|
||||
LCID locale,
|
||||
WORD flags,
|
||||
DISPPARAMS* args,
|
||||
VARIANT* result,
|
||||
EXCEPINFO* error,
|
||||
UINT* argumentError
|
||||
) override;
|
||||
HRESULT STDMETHODCALLTYPE
|
||||
Invoke(DISPID id, REFIID iid, LCID locale, WORD flags, DISPPARAMS* args, VARIANT* result, EXCEPINFO* error, UINT* argumentError) override;
|
||||
|
||||
private:
|
||||
IUnknown& m_site;
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
#include "Client/BrowserRegistry.h"
|
||||
#include "Client/WebBrowser.h"
|
||||
#include "Client/Browser/BrowserRegistry.h"
|
||||
#include "Client/Browser/WebBrowser.h"
|
||||
|
||||
#include <new>
|
||||
|
||||
|
|
@ -28,8 +28,6 @@ void BrowserRegistry::Remove(HWND window) {
|
|||
return;
|
||||
}
|
||||
|
||||
// The reference dereferences the special browser on this miss path before
|
||||
// checking it; a nonnull special owner is a caller precondition here.
|
||||
if (window == this->special->host) {
|
||||
delete this->special;
|
||||
this->special = nullptr;
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
#ifndef RAGNAROK_SOURCE_CLIENT_BROWSERREGISTRY_H
|
||||
#define RAGNAROK_SOURCE_CLIENT_BROWSERREGISTRY_H
|
||||
#ifndef RAGNAROK_SOURCE_CLIENT_BROWSER_BROWSERREGISTRY_H
|
||||
#define RAGNAROK_SOURCE_CLIENT_BROWSER_BROWSERREGISTRY_H
|
||||
|
||||
#include <map>
|
||||
#include <windows.h>
|
||||
|
|
@ -7,9 +7,6 @@
|
|||
class CWebBrowser;
|
||||
struct WebBrowserContext;
|
||||
|
||||
// Borrowed UIWindowMgr browser map and special-browser pointer.
|
||||
// Map nodes survive browser destruction, permitting native callbacks to look up
|
||||
// the original entry. The special alias is cleared before mapped destruction.
|
||||
struct BrowserRegistry {
|
||||
std::map<HWND, CWebBrowser*>& browsers;
|
||||
CWebBrowser*& special;
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
#include "Client/BrowserInterface.h"
|
||||
#include "Client/BrowserSiteAttachment.h"
|
||||
#include "Client/Browser/BrowserInterface.h"
|
||||
#include "Client/Browser/BrowserSiteAttachment.h"
|
||||
|
||||
#include <cstdint>
|
||||
#include <new>
|
||||
|
|
@ -7,8 +7,7 @@
|
|||
// OFFSET: 0x00AB2AB0
|
||||
// FUNCTION: fn_17417
|
||||
bool BrowserSiteAttachment::Attach() {
|
||||
this->site = new (std::nothrow)
|
||||
BrowserClientSite(this->host, *this->sizing.browser, this->factory, this->renderWidth, this->renderHeight);
|
||||
this->site = new (std::nothrow) BrowserClientSite(this->host, *this->sizing.browser, this->factory, this->renderWidth, this->renderHeight);
|
||||
|
||||
IOleObject* object;
|
||||
HRESULT result = this->sizing.browser->QueryInterface(IID_IOleObject, reinterpret_cast<void**>(&object));
|
||||
|
|
@ -22,6 +21,7 @@ bool BrowserSiteAttachment::Attach() {
|
|||
RECT rectangle;
|
||||
GetClientRect(this->host, &rectangle);
|
||||
result = object->DoVerb(OLEIVERB_INPLACEACTIVATE, nullptr, this->site, 0, this->host, &rectangle);
|
||||
|
||||
if (SUCCEEDED(result)) {
|
||||
const int width = rectangle.right - rectangle.left;
|
||||
const int height = rectangle.bottom - rectangle.top;
|
||||
20
Source/Client/Browser/BrowserSiteAttachment.h
Normal file
20
Source/Client/Browser/BrowserSiteAttachment.h
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
#ifndef RAGNAROK_SOURCE_CLIENT_BROWSER_BROWSERSITEATTACHMENT_H
|
||||
#define RAGNAROK_SOURCE_CLIENT_BROWSER_BROWSERSITEATTACHMENT_H
|
||||
|
||||
#include "Client/Browser/BrowserClientSite.h"
|
||||
#include "Client/Browser/BrowserWindowSizing.h"
|
||||
|
||||
struct BrowserSiteAttachment {
|
||||
BrowserWindowSizing& sizing;
|
||||
HWND const& host;
|
||||
BrowserClientSite*& site;
|
||||
DWORD& cookie;
|
||||
BrowserFactory& factory;
|
||||
const int& renderWidth;
|
||||
const int& renderHeight;
|
||||
|
||||
bool Attach();
|
||||
void Detach();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
#include "Client/BrowserWindowSizing.h"
|
||||
#include "Client/Browser/BrowserWindowSizing.h"
|
||||
|
||||
// OFFSET: 0x00AB3060
|
||||
// FUNCTION: fn_17421
|
||||
|
|
@ -67,6 +67,7 @@ void BrowserAuxiliaryVisibility::Show(unsigned char value) {
|
|||
GetClientRect(this->sizing.auxiliary, &rectangle);
|
||||
top = rectangle.bottom - rectangle.top + 4;
|
||||
}
|
||||
|
||||
this->sizing.browser->put_Top(top);
|
||||
|
||||
RECT rectangle;
|
||||
|
|
@ -1,14 +1,10 @@
|
|||
#ifndef RAGNAROK_SOURCE_CLIENT_BROWSERWINDOWSIZING_H
|
||||
#define RAGNAROK_SOURCE_CLIENT_BROWSERWINDOWSIZING_H
|
||||
#ifndef RAGNAROK_SOURCE_CLIENT_BROWSER_BROWSERWINDOWSIZING_H
|
||||
#define RAGNAROK_SOURCE_CLIENT_BROWSER_BROWSERWINDOWSIZING_H
|
||||
|
||||
// clang-format off
|
||||
#include <windows.h>
|
||||
#include <ole2.h>
|
||||
#include <exdisp.h>
|
||||
// clang-format on
|
||||
|
||||
// Borrowed IWebBrowser2 and original browser-owner dimensions. COM lifetime,
|
||||
// activation and navigation are separate; this view owns no references.
|
||||
struct BrowserWindowSizing {
|
||||
IWebBrowser2* const& browser;
|
||||
const int& screenWidth;
|
||||
|
|
@ -18,13 +14,10 @@ struct BrowserWindowSizing {
|
|||
int& width;
|
||||
int& height;
|
||||
|
||||
// Exact screen dimensions are reduced by one, then optional auxiliary
|
||||
// client height plus four is removed. Native setter errors are ignored.
|
||||
void Resize(int requestedWidth, int requestedHeight);
|
||||
void Refresh();
|
||||
};
|
||||
|
||||
// Browser host-site presence, host HWND and auxiliary-visible byte.
|
||||
struct BrowserAuxiliaryVisibility {
|
||||
BrowserWindowSizing& sizing;
|
||||
const bool& hasSite;
|
||||
|
|
@ -1,31 +1,27 @@
|
|||
#include "Client/BrowserClose.h"
|
||||
#include "Client/BrowserCreation.h"
|
||||
#include "Client/BrowserFrame.h"
|
||||
#include "Client/BrowserInputHandoff.h"
|
||||
#include "Client/WebBrowser.h"
|
||||
#include "Client/WebEventReceiver.h"
|
||||
#include "Client/Browser/BrowserClose.h"
|
||||
#include "Client/Browser/BrowserCreation.h"
|
||||
#include "Client/Browser/BrowserFrame.h"
|
||||
#include "Client/Browser/BrowserInputHandoff.h"
|
||||
#include "Client/Browser/WebBrowser.h"
|
||||
#include "Client/Browser/WebEventReceiver.h"
|
||||
|
||||
#include <new>
|
||||
#include <utility>
|
||||
|
||||
namespace {
|
||||
BrowserWindowSizing Sizing(CWebBrowser& owner) {
|
||||
return {owner.browser, owner.screenWidth, owner.screenHeight, owner.rebar,
|
||||
owner.auxiliaryVisible, owner.width, owner.height};
|
||||
return {owner.browser, owner.screenWidth, owner.screenHeight, owner.rebar, owner.auxiliaryVisible, owner.width, owner.height};
|
||||
}
|
||||
}
|
||||
|
||||
// OFFSET: 0x00AB1DE0
|
||||
// FUNCTION: fn_17409
|
||||
CWebBrowser::CWebBrowser(WebBrowserContext& context)
|
||||
: browser(nullptr), externalEvents(nullptr), site(nullptr), host(nullptr), browserWindow(nullptr), cursorState(0),
|
||||
auxiliaryVisible(0), screenWidth(GetSystemMetrics(SM_CXSCREEN)), screenHeight(GetSystemMetrics(SM_CYSCREEN)),
|
||||
cookie(0), rebar(nullptr), combo(nullptr), barHeight(0), width(0), height(0), restoreOption(0),
|
||||
context(&context) {
|
||||
: browser(nullptr), externalEvents(nullptr), site(nullptr), host(nullptr), browserWindow(nullptr), cursorState(0), auxiliaryVisible(0),
|
||||
screenWidth(GetSystemMetrics(SM_CXSCREEN)), screenHeight(GetSystemMetrics(SM_CYSCREEN)), cookie(0), rebar(nullptr), combo(nullptr), barHeight(0),
|
||||
width(0), height(0), restoreOption(0), context(&context) {
|
||||
OutputDebugStringA("CWebBrowser() \n");
|
||||
BrowserInputHandoff handoff{
|
||||
this->restoreOption, context.applicationWindow, context.service, context.mouse, context.activation
|
||||
};
|
||||
BrowserInputHandoff handoff{this->restoreOption, context.applicationWindow, context.service, context.mouse, context.activation};
|
||||
handoff.Enter();
|
||||
}
|
||||
|
||||
|
|
@ -34,10 +30,7 @@ CWebBrowser::CWebBrowser(WebBrowserContext& context)
|
|||
CWebBrowser::~CWebBrowser() {
|
||||
OutputDebugStringA("~CWebBrowser() \n");
|
||||
auto& dependencies = *this->context;
|
||||
BrowserInputHandoff handoff{
|
||||
this->restoreOption, dependencies.applicationWindow, dependencies.service, dependencies.mouse,
|
||||
dependencies.activation
|
||||
};
|
||||
BrowserInputHandoff handoff{this->restoreOption, dependencies.applicationWindow, dependencies.service, dependencies.mouse, dependencies.activation};
|
||||
handoff.Restore();
|
||||
this->Close();
|
||||
}
|
||||
|
|
@ -49,24 +42,13 @@ bool CWebBrowser::Create(int requestedWidth, int requestedHeight) {
|
|||
auto sizing = Sizing(*this);
|
||||
BrowserHostWindow window{this->host, this->browserWindow, dependencies.title, dependencies.hostProcedure};
|
||||
BrowserSiteAttachment attachment{
|
||||
sizing,
|
||||
this->host,
|
||||
this->site,
|
||||
this->cookie,
|
||||
dependencies.popupFactory,
|
||||
dependencies.renderWidth,
|
||||
dependencies.renderHeight
|
||||
sizing, this->host, this->site, this->cookie, dependencies.popupFactory, dependencies.renderWidth, dependencies.renderHeight
|
||||
};
|
||||
BrowserAddressBar addressBar{
|
||||
this->host,
|
||||
this->rebar,
|
||||
this->combo,
|
||||
this->barHeight,
|
||||
this->auxiliaryVisible,
|
||||
dependencies.previousEditProcedure,
|
||||
dependencies.editProcedure
|
||||
this->host, this->rebar, this->combo, this->barHeight, this->auxiliaryVisible, dependencies.previousEditProcedure, dependencies.editProcedure
|
||||
};
|
||||
BrowserCreation creation{this->browser, this->browserWindow, window, attachment, addressBar};
|
||||
|
||||
return creation.Create(dependencies.applicationWindow, dependencies.instance, requestedWidth, requestedHeight);
|
||||
}
|
||||
|
||||
|
|
@ -76,17 +58,11 @@ bool CWebBrowser::Close() {
|
|||
auto& dependencies = *this->context;
|
||||
auto sizing = Sizing(*this);
|
||||
BrowserSiteAttachment attachment{
|
||||
sizing,
|
||||
this->host,
|
||||
this->site,
|
||||
this->cookie,
|
||||
dependencies.popupFactory,
|
||||
dependencies.renderWidth,
|
||||
dependencies.renderHeight
|
||||
sizing, this->host, this->site, this->cookie, dependencies.popupFactory, dependencies.renderWidth, dependencies.renderHeight
|
||||
};
|
||||
BrowserClose operation{attachment, this->browser, this->externalEvents,
|
||||
this->host, this->browserWindow, dependencies.applicationWindow,
|
||||
BrowserClose operation{attachment, this->browser, this->externalEvents, this->host, this->browserWindow, dependencies.applicationWindow,
|
||||
this->cursorState, dependencies.mouse};
|
||||
|
||||
return operation.Close();
|
||||
}
|
||||
|
||||
|
|
@ -96,6 +72,7 @@ bool CWebBrowser::AttachExternalEvents(BrowserRegistry& registry) {
|
|||
auto* receiver = new (std::nothrow) CWebEventReceiver(registry);
|
||||
this->externalEvents = receiver;
|
||||
receiver->AddRef();
|
||||
|
||||
return receiver->Register(this->browser, this->host);
|
||||
}
|
||||
|
||||
|
|
@ -111,9 +88,7 @@ void CWebBrowser::Resize(int requestedWidth, int requestedHeight) {
|
|||
void CWebBrowser::Poll() {
|
||||
auto& dependencies = *this->context;
|
||||
auto sizing = Sizing(*this);
|
||||
BrowserCursor cursor{
|
||||
this->cursorState, dependencies.mouse, dependencies.renderSystem, dependencies.applicationWindow
|
||||
};
|
||||
BrowserCursor cursor{this->cursorState, dependencies.mouse, dependencies.renderSystem, dependencies.applicationWindow};
|
||||
const bool hasExternalEvents = this->externalEvents != nullptr;
|
||||
BrowserFrame frame{sizing, cursor, this->host, this->browserWindow, hasExternalEvents};
|
||||
frame.Poll();
|
||||
|
|
@ -129,7 +104,7 @@ bool CWebBrowser::Navigate(std::string address) {
|
|||
// FUNCTION: fn_17422
|
||||
void CWebBrowser::ShowAuxiliary(unsigned char value) {
|
||||
auto sizing = Sizing(*this);
|
||||
// The original gate is external-event receiver presence at +4, not site +8.
|
||||
|
||||
const bool hasExternalEvents = this->externalEvents != nullptr;
|
||||
BrowserAuxiliaryVisibility visibility{sizing, hasExternalEvents, this->host, this->auxiliaryVisible};
|
||||
visibility.Show(value);
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef RAGNAROK_SOURCE_CLIENT_WEBBROWSER_H
|
||||
#define RAGNAROK_SOURCE_CLIENT_WEBBROWSER_H
|
||||
#ifndef RAGNAROK_SOURCE_CLIENT_BROWSER_WEBBROWSER_H
|
||||
#define RAGNAROK_SOURCE_CLIENT_BROWSER_WEBBROWSER_H
|
||||
|
||||
#include "Client/BrowserInterface.h"
|
||||
#include "Client/Browser/BrowserInterface.h"
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
|
|
@ -11,13 +11,8 @@ class CRenderSystemBase;
|
|||
struct ServiceOptions;
|
||||
struct BrowserRegistry;
|
||||
struct BrowserFactory;
|
||||
namespace client {
|
||||
struct ApplicationActivation;
|
||||
}
|
||||
struct ApplicationActivation;
|
||||
|
||||
// Borrowed application globals, concrete popup factory and native procedures.
|
||||
// All must outlive the browser. Renderer dimensions retain their original
|
||||
// separately owned globals rather than querying virtuals during popup dispatch.
|
||||
struct WebBrowserContext {
|
||||
HWND const& applicationWindow;
|
||||
HINSTANCE const& instance;
|
||||
|
|
@ -25,7 +20,7 @@ struct WebBrowserContext {
|
|||
CMouse& mouse;
|
||||
CRenderSystemBase& renderSystem;
|
||||
ServiceOptions& service;
|
||||
client::ApplicationActivation& activation;
|
||||
ApplicationActivation& activation;
|
||||
BrowserFactory& popupFactory;
|
||||
const int& renderWidth;
|
||||
const int& renderHeight;
|
||||
|
|
@ -34,8 +29,6 @@ struct WebBrowserContext {
|
|||
WNDPROC& previousEditProcedure;
|
||||
};
|
||||
|
||||
// Original nonpolymorphic 64-byte CWebBrowser prefix. Context follows it as a
|
||||
// host dependency view; no original executable addresses are used at runtime.
|
||||
class CWebBrowser {
|
||||
public:
|
||||
explicit CWebBrowser(WebBrowserContext& context);
|
||||
|
|
@ -1,13 +1,15 @@
|
|||
#include "Client/BrowserRegistry.h"
|
||||
#include "Client/WebEventReceiver.h"
|
||||
#include "Client/Browser/BrowserRegistry.h"
|
||||
#include "Client/Browser/WebEventReceiver.h"
|
||||
|
||||
#include <exdispid.h>
|
||||
#include <mshtmdid.h>
|
||||
|
||||
#include <mshtml.h>
|
||||
|
||||
// OFFSET: 0x00AB3710
|
||||
// FUNCTION: fn_17424
|
||||
CWebEventReceiver::CWebEventReceiver(BrowserRegistry& registry)
|
||||
: m_references(0), m_browser(nullptr), m_browserCookie(0), m_document(nullptr), m_documentCookie(0),
|
||||
m_host(nullptr), m_registry(registry) {
|
||||
: m_references(0), m_browser(nullptr), m_browserCookie(0), m_document(nullptr), m_documentCookie(0), m_host(nullptr), m_registry(registry) {
|
||||
OutputDebugStringA("CWebEventReceiver() \n");
|
||||
}
|
||||
|
||||
|
|
@ -22,6 +24,7 @@ bool CWebEventReceiver::Register(IWebBrowser2* browser, HWND host) {
|
|||
this->m_browser = browser;
|
||||
this->m_host = host;
|
||||
this->m_browser->AddRef();
|
||||
|
||||
return SUCCEEDED(AdviseBrowserEvents(this->m_browser, this, DIID_DWebBrowserEvents2, &this->m_browserCookie));
|
||||
}
|
||||
|
||||
|
|
@ -98,20 +101,17 @@ HRESULT CWebEventReceiver::Disconnect() {
|
|||
|
||||
// OFFSET: 0x00AB3B20
|
||||
// FUNCTION: fn_17433
|
||||
HRESULT STDMETHODCALLTYPE
|
||||
CWebEventReceiver::Invoke(DISPID id, REFIID, LCID, WORD, DISPPARAMS* args, VARIANT*, EXCEPINFO*, UINT*) {
|
||||
if (id == 253) {
|
||||
HRESULT STDMETHODCALLTYPE CWebEventReceiver::Invoke(DISPID id, REFIID, LCID, WORD, DISPPARAMS* args, VARIANT*, EXCEPINFO*, UINT*) {
|
||||
if (id == DISPID_ONQUIT) {
|
||||
return this->Disconnect();
|
||||
}
|
||||
|
||||
if (id == 259) {
|
||||
if (id == DISPID_DOCUMENTCOMPLETE) {
|
||||
IDispatch* browserIdentity = nullptr;
|
||||
if (FAILED(this->m_browser->QueryInterface(IID_IDispatch, reinterpret_cast<void**>(&browserIdentity)))) {
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
// DocumentComplete's pDisp is the second reverse-order VARIANT. The
|
||||
// reference retains browserIdentity on an identity mismatch.
|
||||
if (args->rgvarg[1].pdispVal != browserIdentity) {
|
||||
return S_OK;
|
||||
}
|
||||
|
|
@ -125,7 +125,7 @@ CWebEventReceiver::Invoke(DISPID id, REFIID, LCID, WORD, DISPPARAMS* args, VARIA
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
if (id != -602 && id != static_cast<DISPID>(0x8001000A) && id != 1023) {
|
||||
if (id != DISPID_HTMLDOCUMENTEVENTS2_ONKEYDOWN && id != DISPID_HTMLDOCUMENTEVENTS2_ONHELP && id != DISPID_HTMLDOCUMENTEVENTS2_ONCONTEXTMENU) {
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
|
@ -134,26 +134,26 @@ CWebEventReceiver::Invoke(DISPID id, REFIID, LCID, WORD, DISPPARAMS* args, VARIA
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
if (id == -602) {
|
||||
if (id == DISPID_HTMLDOCUMENTEVENTS2_ONKEYDOWN) {
|
||||
long key = 0;
|
||||
if (FAILED(event->get_keyCode(&key))) {
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
switch (key) {
|
||||
case 18:
|
||||
case 112:
|
||||
case 114:
|
||||
case 115:
|
||||
case 122:
|
||||
case VK_MENU:
|
||||
case VK_F1:
|
||||
case VK_F3:
|
||||
case VK_F4:
|
||||
case VK_F11:
|
||||
break;
|
||||
default:
|
||||
// Deliberately retained reference on the original non-filtered branch.
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
|
||||
if (id != 1023) {
|
||||
if (id != DISPID_HTMLDOCUMENTEVENTS2_ONCONTEXTMENU) {
|
||||
event->put_keyCode(0);
|
||||
}
|
||||
|
||||
|
|
@ -163,5 +163,6 @@ CWebEventReceiver::Invoke(DISPID id, REFIID, LCID, WORD, DISPPARAMS* args, VARIA
|
|||
cancelled.boolVal = VARIANT_FALSE;
|
||||
event->put_returnValue(cancelled);
|
||||
event->Release();
|
||||
return id == -602 ? S_FALSE : S_OK;
|
||||
|
||||
return id == DISPID_HTMLDOCUMENTEVENTS2_ONKEYDOWN ? S_FALSE : S_OK;
|
||||
}
|
||||
|
|
@ -1,13 +1,10 @@
|
|||
#ifndef RAGNAROK_SOURCE_CLIENT_WEBEVENTRECEIVER_H
|
||||
#define RAGNAROK_SOURCE_CLIENT_WEBEVENTRECEIVER_H
|
||||
#ifndef RAGNAROK_SOURCE_CLIENT_BROWSER_WEBEVENTRECEIVER_H
|
||||
#define RAGNAROK_SOURCE_CLIENT_BROWSER_WEBEVENTRECEIVER_H
|
||||
|
||||
#include "Client/BrowserInterface.h"
|
||||
#include "Client/Browser/BrowserInterface.h"
|
||||
|
||||
struct BrowserRegistry;
|
||||
|
||||
// Original receiver starts with zero references. Caller acquires its owning
|
||||
// reference before registration. Destruction only reports diagnostics; explicit
|
||||
// Disconnect performs COM and registry teardown, not the destructor.
|
||||
class CWebEventReceiver final : public IDispatch {
|
||||
public:
|
||||
explicit CWebEventReceiver(BrowserRegistry& registry);
|
||||
|
|
@ -20,16 +17,8 @@ public:
|
|||
HRESULT STDMETHODCALLTYPE GetTypeInfoCount(UINT* count) override;
|
||||
HRESULT STDMETHODCALLTYPE GetTypeInfo(UINT index, LCID locale, ITypeInfo** output) override;
|
||||
HRESULT STDMETHODCALLTYPE GetIDsOfNames(REFIID iid, LPOLESTR* names, UINT count, LCID locale, DISPID* ids) override;
|
||||
HRESULT STDMETHODCALLTYPE Invoke(
|
||||
DISPID id,
|
||||
REFIID iid,
|
||||
LCID locale,
|
||||
WORD flags,
|
||||
DISPPARAMS* args,
|
||||
VARIANT* result,
|
||||
EXCEPINFO* error,
|
||||
UINT* argumentError
|
||||
) override;
|
||||
HRESULT STDMETHODCALLTYPE
|
||||
Invoke(DISPID id, REFIID iid, LCID locale, WORD flags, DISPPARAMS* args, VARIANT* result, EXCEPINFO* error, UINT* argumentError) override;
|
||||
|
||||
private:
|
||||
~CWebEventReceiver();
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
#ifndef RAGNAROK_SOURCE_CLIENT_BROWSERADDRESSBAR_H
|
||||
#define RAGNAROK_SOURCE_CLIENT_BROWSERADDRESSBAR_H
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
// Borrowed host, rebar, combo, height, visible, and shared
|
||||
// previous-edit-procedure global. Caller initializes common controls and supplies
|
||||
// the actual BrowserAddressEdit thunk. Native verification requires v6 controls
|
||||
// for the original 100-byte x86 band; startup activation policy is not recovered.
|
||||
// Failed creation retains native children; normal host destruction owns them.
|
||||
struct BrowserAddressBar {
|
||||
HWND const& host;
|
||||
HWND& rebar;
|
||||
HWND& combo;
|
||||
int& height;
|
||||
const unsigned char& visible;
|
||||
WNDPROC& previous;
|
||||
WNDPROC procedure;
|
||||
|
||||
bool Create(int width, int height);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
#ifndef RAGNAROK_SOURCE_CLIENT_BROWSERADDRESSEDIT_H
|
||||
#define RAGNAROK_SOURCE_CLIENT_BROWSERADDRESSEDIT_H
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
// Borrowed original subclass procedure and active browser-host selection.
|
||||
// Null activeHost denotes no active CWebBrowser, not a null HWND field inside
|
||||
// an otherwise active object.
|
||||
struct BrowserAddressEdit {
|
||||
WNDPROC const& previous;
|
||||
HWND const* const& activeHost;
|
||||
|
||||
LRESULT Message(HWND window, UINT message, WPARAM value, LPARAM flags);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
#ifndef RAGNAROK_SOURCE_CLIENT_BROWSERCLOSE_H
|
||||
#define RAGNAROK_SOURCE_CLIENT_BROWSERCLOSE_H
|
||||
|
||||
#include "Client/BrowserSiteAttachment.h"
|
||||
|
||||
class CMouse;
|
||||
|
||||
// Borrowed original browser fields. External events use a separate COM reference
|
||||
// independent of the client-site dispatch dependency. Auxiliary HWNDs and
|
||||
// cookie remain untouched even after their host destroys the native children.
|
||||
struct BrowserClose {
|
||||
BrowserSiteAttachment& attachment;
|
||||
IWebBrowser2*& browser;
|
||||
IUnknown*& externalEvents;
|
||||
HWND& host;
|
||||
HWND const& browserWindow;
|
||||
HWND const& applicationWindow;
|
||||
int& cursorState;
|
||||
CMouse& mouse;
|
||||
|
||||
bool Close();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
#ifndef RAGNAROK_SOURCE_CLIENT_BROWSERCREATION_H
|
||||
#define RAGNAROK_SOURCE_CLIENT_BROWSERCREATION_H
|
||||
|
||||
#include "Client/BrowserAddressBar.h"
|
||||
#include "Client/BrowserHostWindow.h"
|
||||
#include "Client/BrowserSiteAttachment.h"
|
||||
|
||||
// Views must refer to the same CWebBrowser fields. Caller supplies the complete
|
||||
// host procedure, edit subclass and site event dependency. No rollback on error:
|
||||
// browser, host, site and native children remain published at their original steps.
|
||||
struct BrowserCreation {
|
||||
IWebBrowser2*& browser;
|
||||
HWND& browserWindow;
|
||||
BrowserHostWindow& window;
|
||||
BrowserSiteAttachment& attachment;
|
||||
BrowserAddressBar& addressBar;
|
||||
|
||||
bool Create(HWND parent, HINSTANCE instance, int width, int height);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
#ifndef RAGNAROK_SOURCE_CLIENT_BROWSERCURSOR_H
|
||||
#define RAGNAROK_SOURCE_CLIENT_BROWSERCURSOR_H
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
class CMouse;
|
||||
class CRenderSystemBase;
|
||||
|
||||
// Borrowed CWebBrowser cursor state and the actual global mouse/render
|
||||
// owners. ShowCursor receives the full integer, not a normalized boolean.
|
||||
struct BrowserCursor {
|
||||
int& state;
|
||||
CMouse& mouse;
|
||||
CRenderSystemBase& renderSystem;
|
||||
HWND const& applicationWindow;
|
||||
|
||||
void Set(int value);
|
||||
void Poll();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
#ifndef RAGNAROK_SOURCE_CLIENT_BROWSERFRAME_H
|
||||
#define RAGNAROK_SOURCE_CLIENT_BROWSERFRAME_H
|
||||
|
||||
#include "Client/BrowserCursor.h"
|
||||
#include "Client/BrowserWindowSizing.h"
|
||||
|
||||
// Borrowed original browser owner. Presence means the separate external event
|
||||
// receiver is attached, not merely that an OLE client site exists.
|
||||
struct BrowserFrame {
|
||||
BrowserWindowSizing& sizing;
|
||||
BrowserCursor& cursor;
|
||||
HWND const& host;
|
||||
HWND const& browserWindow;
|
||||
const bool& hasExternalEvents;
|
||||
|
||||
void Normalize();
|
||||
void Poll();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
#ifndef RAGNAROK_SOURCE_CLIENT_BROWSERHOSTWINDOW_H
|
||||
#define RAGNAROK_SOURCE_CLIENT_BROWSERHOSTWINDOW_H
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
// Borrowed CWebBrowser host and browser HWND, application
|
||||
// title and complete browser window procedure. This operation does not replace
|
||||
// that procedure with DefWindowProc or invent the browser host-site lifecycle.
|
||||
struct BrowserHostWindow {
|
||||
HWND& host;
|
||||
HWND const& browser;
|
||||
const char* const& title;
|
||||
WNDPROC procedure;
|
||||
|
||||
bool Create(HWND parent, HINSTANCE instance, int width, int height);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
#ifndef RAGNAROK_SOURCE_CLIENT_BROWSERINPUTHANDOFF_H
|
||||
#define RAGNAROK_SOURCE_CLIENT_BROWSERINPUTHANDOFF_H
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
class CMouse;
|
||||
struct ServiceOptions;
|
||||
namespace client {
|
||||
struct ApplicationActivation;
|
||||
}
|
||||
|
||||
// Borrowed original CWebBrowser service-option latch, main HWND and global
|
||||
// input owners. Restoration retains the latch; it is not a one-shot operation.
|
||||
struct BrowserInputHandoff {
|
||||
unsigned char& restoreOption;
|
||||
HWND const& applicationWindow;
|
||||
ServiceOptions& service;
|
||||
CMouse& mouse;
|
||||
client::ApplicationActivation& activation;
|
||||
|
||||
void Enter();
|
||||
void Restore();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
#ifndef RAGNAROK_SOURCE_CLIENT_BROWSERINTERFACE_H
|
||||
#define RAGNAROK_SOURCE_CLIENT_BROWSERINTERFACE_H
|
||||
|
||||
// clang-format off
|
||||
#include <windows.h>
|
||||
#include <ole2.h>
|
||||
#include <exdisp.h>
|
||||
// clang-format on
|
||||
|
||||
#include <string>
|
||||
|
||||
// Caller supplies the original owner fields and controls COM initialization
|
||||
// and release. Successful creation publishes HWND only when browser is nonnull;
|
||||
// get_HWND failure does not change the creation result.
|
||||
bool CreateBrowserInterface(IWebBrowser2*& browser, HWND& window);
|
||||
|
||||
// Distinct original local-server route; never falls back to the in-process
|
||||
// control. Success reparents its HWND and clears Top, Left and StatusBar.
|
||||
bool CreateExternalBrowserInterface(IWebBrowser2*& browser, HWND& window, HWND const& host);
|
||||
|
||||
// Navigation's four optional arguments alias one VT_EMPTY VARIANT. Host show,
|
||||
// browser visibility and title publication occur even when Navigate fails.
|
||||
bool NavigateBrowser(IWebBrowser2* const& browser, HWND const& host, HWND const& title, std::string address);
|
||||
|
||||
// Connection-point helpers retain native HRESULTs; cookie writes belong to
|
||||
// Advise. Release the connection point before its container on every path.
|
||||
HRESULT AdviseBrowserEvents(IUnknown* source, IUnknown* sink, REFIID events, DWORD* cookie);
|
||||
HRESULT UnadviseBrowserEvents(IUnknown* source, REFIID events, DWORD cookie);
|
||||
|
||||
#endif
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
#ifndef RAGNAROK_SOURCE_CLIENT_BROWSERSITEATTACHMENT_H
|
||||
#define RAGNAROK_SOURCE_CLIENT_BROWSERSITEATTACHMENT_H
|
||||
|
||||
#include "Client/BrowserClientSite.h"
|
||||
#include "Client/BrowserWindowSizing.h"
|
||||
|
||||
// Borrowed original owner fields, real popup factory and renderer dimensions.
|
||||
// Site publication precedes COM work and remains on failure. Detach destroys the
|
||||
// site even when QueryInterface fails; it does not clear the COM client site.
|
||||
struct BrowserSiteAttachment {
|
||||
BrowserWindowSizing& sizing;
|
||||
HWND const& host;
|
||||
BrowserClientSite*& site;
|
||||
DWORD& cookie;
|
||||
BrowserFactory& factory;
|
||||
const int& renderWidth;
|
||||
const int& renderHeight;
|
||||
|
||||
bool Attach();
|
||||
void Detach();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -1,17 +1,14 @@
|
|||
#include "Client/ClientOptions.h"
|
||||
|
||||
#include <bit>
|
||||
|
||||
// OFFSET: 0x0091BE20
|
||||
// FUNCTION: fn_12610
|
||||
int ClientOptions::Get(int id) const {
|
||||
return std::bit_cast<int>(static_cast<std::uint32_t>(this->values.Get(id)));
|
||||
return static_cast<int>(this->values.Get(id));
|
||||
}
|
||||
|
||||
// OFFSET: 0x005E7970
|
||||
// FUNCTION: fn_03937
|
||||
void ClientOptions::Set(int id, int value, int extra) {
|
||||
const std::uint64_t bits =
|
||||
static_cast<std::uint32_t>(value) | (static_cast<std::uint64_t>(static_cast<std::uint32_t>(extra)) << 32);
|
||||
this->values.Set(id, std::bit_cast<std::int64_t>(bits));
|
||||
const std::uint64_t bits = static_cast<std::uint32_t>(value) | (static_cast<std::uint64_t>(extra) << 32);
|
||||
this->values.Set(id, static_cast<std::int64_t>(bits));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@
|
|||
|
||||
#include "Contents/InstantVar.h"
|
||||
|
||||
// Low/high-word client operations on its CInstantVar at +0x7FA8.
|
||||
struct ClientOptions {
|
||||
CInstantVar& values;
|
||||
int Get(int id) const;
|
||||
|
|
|
|||
|
|
@ -1,12 +0,0 @@
|
|||
#ifndef RAGNAROK_SOURCE_CLIENT_ERRORDIALOG_H
|
||||
#define RAGNAROK_SOURCE_CLIENT_ERRORDIALOG_H
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
class CRenderSystemBase;
|
||||
|
||||
// Obtained through the render-system owner.
|
||||
// Keep the real owner dependency explicit until its lifecycle is reconstructed.
|
||||
int ShowErrorDialog(CRenderSystemBase* renderSystem, const char* text, UINT type);
|
||||
|
||||
#endif
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
#include "Client/ImeInput.h"
|
||||
#include "Client/TraditionalKeyInput.h"
|
||||
#include "Utility/LanguageCharset.h"
|
||||
#include "Client/Input/ImeInput.h"
|
||||
#include "Client/Input/TraditionalKeyInput.h"
|
||||
#include "Utility/Text/LanguageCharset.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
|
|
@ -10,6 +10,7 @@
|
|||
// FUNCTION: fn_17793
|
||||
LRESULT ImeInput::Message(HWND, UINT message, WPARAM value, LPARAM flags, std::uint8_t& handled) {
|
||||
const auto options = static_cast<std::uint16_t>(flags);
|
||||
|
||||
switch (message) {
|
||||
case WM_INPUTLANGCHANGE:
|
||||
this->language = options;
|
||||
|
|
@ -48,13 +49,13 @@ LRESULT ImeInput::Message(HWND, UINT message, WPARAM value, LPARAM flags, std::u
|
|||
if (context) {
|
||||
WCHAR wide[256];
|
||||
char converted[256];
|
||||
const auto bytes =
|
||||
static_cast<std::uint32_t>(ImmGetCompositionStringW(context, GCS_RESULTSTR, wide, sizeof(wide)));
|
||||
const unsigned size =
|
||||
WideCharToMultiByte(this->codePage, 0, wide, bytes >> 1, converted, sizeof(converted), nullptr, nullptr);
|
||||
const auto bytes = static_cast<std::uint32_t>(ImmGetCompositionStringW(context, GCS_RESULTSTR, wide, sizeof(wide)));
|
||||
const unsigned size = WideCharToMultiByte(this->codePage, 0, wide, bytes >> 1, converted, sizeof(converted), nullptr, nullptr);
|
||||
|
||||
if (size >= sizeof(converted)) {
|
||||
__fastfail(8);
|
||||
__fastfail(FAST_FAIL_RANGE_CHECK_FAILURE);
|
||||
}
|
||||
|
||||
converted[size] = 0;
|
||||
ImmReleaseContext(this->input.window, context);
|
||||
this->input.Insert(converted);
|
||||
|
|
@ -78,6 +79,7 @@ LRESULT ImeInput::Message(HWND, UINT message, WPARAM value, LPARAM flags, std::u
|
|||
} else {
|
||||
this->input.compositionState = 0;
|
||||
}
|
||||
|
||||
ImmReleaseContext(this->input.window, context);
|
||||
} else {
|
||||
this->input.compositionState = 0;
|
||||
|
|
@ -109,5 +111,6 @@ const char* ImeInput::Candidate(int index) const {
|
|||
const WCHAR* text = reinterpret_cast<const WCHAR*>(bytes + this->candidateList->dwOffset[index]);
|
||||
const unsigned size = WideCharToMultiByte(this->codePage, 0, text, -1, output, sizeof(output), nullptr, nullptr);
|
||||
output[std::min<unsigned>(size, 255)] = 0;
|
||||
|
||||
return output;
|
||||
}
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef RAGNAROK_SOURCE_CLIENT_IMEINPUT_H
|
||||
#define RAGNAROK_SOURCE_CLIENT_IMEINPUT_H
|
||||
#ifndef RAGNAROK_SOURCE_CLIENT_INPUT_IMEINPUT_H
|
||||
#define RAGNAROK_SOURCE_CLIENT_INPUT_IMEINPUT_H
|
||||
|
||||
#include "Client/TextInputBuffer.h"
|
||||
#include "Client/Input/TextInputBuffer.h"
|
||||
|
||||
#include <cstdint>
|
||||
#include <imm.h>
|
||||
|
|
@ -9,8 +9,6 @@
|
|||
|
||||
struct TraditionalKeyInput;
|
||||
|
||||
// Borrowed CLanguage fields, with optional concrete CLanguageTC key view.
|
||||
// Base/TH/ARB composition hooks are established empty entries.
|
||||
struct ImeInput {
|
||||
TextInputBuffer& input;
|
||||
std::uint16_t& language;
|
||||
|
|
@ -24,11 +22,8 @@ struct ImeInput {
|
|||
int& compositionCursor;
|
||||
TraditionalKeyInput* traditional;
|
||||
|
||||
// Original ignores the passed HWND and uses the global main-window handle
|
||||
// borrowed by input. Flags are truncated to the low WORD.
|
||||
LRESULT Message(HWND unused, UINT message, WPARAM value, LPARAM flags, std::uint8_t& handled);
|
||||
// Shared 256-byte output; later successful lookups overwrite prior strings.
|
||||
// Original checks index < count only (no negative-index guard).
|
||||
|
||||
const char* Candidate(int index) const;
|
||||
};
|
||||
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
#include "Client/InputCharset.h"
|
||||
#include "Utility/LanguageCharset.h"
|
||||
#include "Client/Input/InputCharset.h"
|
||||
#include "Utility/Text/LanguageCharset.h"
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
#ifndef RAGNAROK_SOURCE_CLIENT_INPUTCHARSET_H
|
||||
#define RAGNAROK_SOURCE_CLIENT_INPUTCHARSET_H
|
||||
#ifndef RAGNAROK_SOURCE_CLIENT_INPUT_INPUTCHARSET_H
|
||||
#define RAGNAROK_SOURCE_CLIENT_INPUT_INPUTCHARSET_H
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
|
|
@ -9,7 +9,7 @@ struct InputCharset {
|
|||
const std::uint16_t& alternateLanguage;
|
||||
|
||||
const char* Prefix(bool alternate) const;
|
||||
// Shared selection used by composition refresh/language-change handling.
|
||||
|
||||
unsigned CodePage(unsigned fallback) const;
|
||||
};
|
||||
|
||||
|
|
@ -1,11 +1,8 @@
|
|||
#include "Client/Mouse.h"
|
||||
#include "Render/DCSurface.h"
|
||||
#include "Client/Input/Mouse.h"
|
||||
#include "Render/DeviceContext/DCSurface.h"
|
||||
|
||||
#include <bit>
|
||||
#include <windows.h>
|
||||
// clang-format off
|
||||
#include <mmsystem.h>
|
||||
// clang-format on
|
||||
#include <timeapi.h>
|
||||
|
||||
// OFFSET: 0x006370C0
|
||||
// FUNCTION: fn_04724
|
||||
|
|
@ -20,11 +17,12 @@ void CMouse::Update() {
|
|||
return;
|
||||
}
|
||||
|
||||
this->deltaX = std::bit_cast<int>(static_cast<std::uint32_t>(this->pendingX) - static_cast<std::uint32_t>(this->x));
|
||||
this->deltaY = std::bit_cast<int>(static_cast<std::uint32_t>(this->pendingY) - static_cast<std::uint32_t>(this->y));
|
||||
this->deltaX = this->pendingX - this->x;
|
||||
this->deltaY = this->pendingY - this->y;
|
||||
this->x = this->pendingX;
|
||||
this->y = this->pendingY;
|
||||
const std::uint32_t now = timeGetTime();
|
||||
|
||||
for (unsigned index = 0; index < 2; ++index) {
|
||||
if (this->deltaX != 0 || this->deltaY != 0) {
|
||||
this->pressTicks[index] = now - this->doubleClickTime;
|
||||
|
|
@ -71,6 +69,7 @@ int CMouse::Center() {
|
|||
const int halfHeight = static_cast<int>(GetRenderSystemHolder()->Height()) / 2;
|
||||
this->pendingY = halfHeight;
|
||||
this->y = halfHeight;
|
||||
|
||||
return halfHeight;
|
||||
}
|
||||
|
||||
|
|
@ -120,7 +119,7 @@ void CMouse::Message(CMouse& global, HWND mainWindow, HWND source, UINT message,
|
|||
this->pendingButtons[1] = 0;
|
||||
break;
|
||||
case WM_MOUSEWHEEL:
|
||||
this->pendingWheel = std::bit_cast<std::int16_t>(static_cast<std::uint16_t>(keys >> 16));
|
||||
this->pendingWheel = GET_WHEEL_DELTA_WPARAM(keys);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,11 +1,9 @@
|
|||
#ifndef RAGNAROK_SOURCE_CLIENT_MOUSE_H
|
||||
#define RAGNAROK_SOURCE_CLIENT_MOUSE_H
|
||||
#ifndef RAGNAROK_SOURCE_CLIENT_INPUT_MOUSE_H
|
||||
#define RAGNAROK_SOURCE_CLIENT_INPUT_MOUSE_H
|
||||
|
||||
#include <cstdint>
|
||||
#include <windows.h>
|
||||
|
||||
// RTTI CMouse. Defaults below are the original
|
||||
// static-data initializer, not evidence of a separate allocating constructor.
|
||||
class CMouse {
|
||||
public:
|
||||
virtual ~CMouse();
|
||||
|
|
@ -14,9 +12,7 @@ public:
|
|||
int Center();
|
||||
void SetX(int value);
|
||||
void SetY(int value);
|
||||
// Message position comes from GetCursorPos/mainWindow, not lParam or source.
|
||||
// The original resets the global mouse on first message; pass that owner
|
||||
// separately so non-global instances retain the same distinction.
|
||||
|
||||
void Message(CMouse& global, HWND mainWindow, HWND source, UINT message, WPARAM keys, LPARAM unused);
|
||||
|
||||
/* 0004 */ int x = 0;
|
||||
|
|
@ -1,9 +1,8 @@
|
|||
#include "Client/TextInputBuffer.h"
|
||||
#include "UI/UIWindow.h"
|
||||
#include "UI/WindowManagerWindows.h"
|
||||
#include "Client/Input/TextInputBuffer.h"
|
||||
#include "UI/Window/UIWindow.h"
|
||||
#include "UI/Window/WindowManagerWindows.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <bit>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <imm.h>
|
||||
|
|
@ -14,7 +13,7 @@ void TextInputBuffer::CancelComposition() {
|
|||
HIMC context = ImmGetContext(this->window);
|
||||
|
||||
if (context) {
|
||||
ImmNotifyIME(context, 0x15, 4, 0);
|
||||
ImmNotifyIME(context, NI_COMPOSITIONSTR, CPS_CANCEL, 0);
|
||||
ImmReleaseContext(this->window, context);
|
||||
}
|
||||
|
||||
|
|
@ -34,8 +33,7 @@ void TextInputBuffer::DeleteSelection() {
|
|||
}
|
||||
|
||||
const int begin = std::min(this->cursor, this->anchor);
|
||||
const auto length =
|
||||
static_cast<std::uint32_t>(std::max(this->cursor, this->anchor)) - static_cast<std::uint32_t>(begin);
|
||||
const int length = std::max(this->cursor, this->anchor) - begin;
|
||||
this->text.erase(static_cast<std::size_t>(begin), length);
|
||||
this->cursor = begin;
|
||||
this->anchor = begin;
|
||||
|
|
@ -50,9 +48,7 @@ void TextInputBuffer::DeleteSelection() {
|
|||
void TextInputBuffer::Insert(const char* value) {
|
||||
this->DeleteSelection();
|
||||
this->text.insert(static_cast<std::size_t>(this->cursor), value, std::strlen(value));
|
||||
this->anchor = std::bit_cast<std::int32_t>(
|
||||
static_cast<std::uint32_t>(std::strlen(value)) + static_cast<std::uint32_t>(this->cursor)
|
||||
);
|
||||
this->anchor = this->cursor + static_cast<int>(std::strlen(value));
|
||||
this->cursor = this->anchor;
|
||||
|
||||
if (this->suggestionsEnabled && this->chatOpen && this->chatInput && this->focused == this->chatInput) {
|
||||
|
|
@ -77,9 +73,7 @@ void TextInputBuffer::CopyDisplayText(std::string& output) const {
|
|||
}
|
||||
|
||||
if (!this->candidate.empty()) {
|
||||
output.insert(
|
||||
static_cast<std::size_t>(this->cursor), this->candidate.c_str(), std::strlen(this->candidate.c_str())
|
||||
);
|
||||
output.insert(static_cast<std::size_t>(this->cursor), this->candidate.c_str(), std::strlen(this->candidate.c_str()));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -102,8 +96,7 @@ void TextInputBuffer::RefreshComposition(unsigned codePage) {
|
|||
WCHAR wide[256];
|
||||
char converted[256];
|
||||
const auto bytes = static_cast<std::uint32_t>(ImmGetCompositionStringW(context, GCS_COMPSTR, wide, sizeof(wide)));
|
||||
const unsigned size =
|
||||
WideCharToMultiByte(codePage, 0, wide, bytes >> 1, converted, sizeof(converted), nullptr, nullptr);
|
||||
const unsigned size = WideCharToMultiByte(codePage, 0, wide, bytes >> 1, converted, sizeof(converted), nullptr, nullptr);
|
||||
ImmReleaseContext(this->window, context);
|
||||
this->candidate.assign(converted, size);
|
||||
|
||||
|
|
@ -122,8 +115,7 @@ void TextInputBuffer::RefreshComposition(unsigned codePage) {
|
|||
// OFFSET: 0x00ACD5C0
|
||||
// FUNCTION: fn_17765
|
||||
void TextInputBuffer::CopySelection(bool password) {
|
||||
const auto difference = static_cast<std::uint32_t>(this->cursor) - static_cast<std::uint32_t>(this->anchor);
|
||||
const auto length = std::bit_cast<std::int32_t>(difference) < 0 ? 0u - difference : difference;
|
||||
const int length = std::max(this->cursor, this->anchor) - std::min(this->cursor, this->anchor);
|
||||
if (!length || !OpenClipboard(this->window)) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -138,6 +130,7 @@ void TextInputBuffer::CopySelection(bool password) {
|
|||
} else {
|
||||
std::memcpy(data, this->text.data() + begin, length);
|
||||
}
|
||||
|
||||
data[length] = 0;
|
||||
GlobalUnWire(memory);
|
||||
EmptyClipboard();
|
||||
|
|
@ -200,7 +193,7 @@ void TextInputBuffer::MoveForward(unsigned codePage) {
|
|||
const auto length = static_cast<std::uint32_t>(this->text.size());
|
||||
const auto position = static_cast<std::uint32_t>(this->cursor);
|
||||
if (position > length) {
|
||||
this->cursor = std::bit_cast<int>(length);
|
||||
this->cursor = static_cast<int>(length);
|
||||
} else if (position < length) {
|
||||
const char* begin = this->text.c_str();
|
||||
this->cursor = static_cast<int>(CharNextExA(static_cast<WORD>(codePage), begin + position, 0) - begin);
|
||||
|
|
@ -214,6 +207,7 @@ void TextInputBuffer::Character(unsigned value, LPARAM, unsigned codePage) {
|
|||
if (this->cursor == this->anchor) {
|
||||
this->MoveBack(codePage);
|
||||
}
|
||||
|
||||
this->DeleteSelection();
|
||||
return;
|
||||
}
|
||||
|
|
@ -222,8 +216,6 @@ void TextInputBuffer::Character(unsigned value, LPARAM, unsigned codePage) {
|
|||
return;
|
||||
}
|
||||
|
||||
// Keep the original little-endian DWORD representation and stop at its first
|
||||
// zero byte; valid WM_CHAR payloads provide that terminator within the word.
|
||||
char bytes[sizeof(value)];
|
||||
std::memcpy(bytes, &value, sizeof(value));
|
||||
this->Insert(bytes);
|
||||
|
|
@ -232,13 +224,7 @@ void TextInputBuffer::Character(unsigned value, LPARAM, unsigned codePage) {
|
|||
// OFFSET: 0x00ACE880
|
||||
// FUNCTION: fn_17792
|
||||
void TextInputBuffer::KeyDown(
|
||||
unsigned key,
|
||||
LPARAM,
|
||||
unsigned codePage,
|
||||
bool password,
|
||||
UIWindow* blockedPasteFocus,
|
||||
WindowManagerWindows& windows,
|
||||
UIWindow* const& chatArrows
|
||||
unsigned key, LPARAM, unsigned codePage, bool password, UIWindow* blockedPasteFocus, WindowManagerWindows& windows, UIWindow* const& chatArrows
|
||||
) {
|
||||
const auto cut = [&]() {
|
||||
this->CopySelection(password);
|
||||
|
|
@ -266,6 +252,7 @@ void TextInputBuffer::KeyDown(
|
|||
cut();
|
||||
break;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -285,6 +272,7 @@ void TextInputBuffer::KeyDown(
|
|||
this->cursor = std::max(static_cast<int>(this->text.size()), 0);
|
||||
break;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -305,6 +293,7 @@ void TextInputBuffer::KeyDown(
|
|||
} else {
|
||||
this->MoveForward(codePage);
|
||||
}
|
||||
|
||||
this->anchor = this->cursor;
|
||||
}
|
||||
break;
|
||||
57
Source/Client/Input/TextInputBuffer.h
Normal file
57
Source/Client/Input/TextInputBuffer.h
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
#ifndef RAGNAROK_SOURCE_CLIENT_INPUT_TEXTINPUTBUFFER_H
|
||||
#define RAGNAROK_SOURCE_CLIENT_INPUT_TEXTINPUTBUFFER_H
|
||||
|
||||
#include <string>
|
||||
#include <windows.h>
|
||||
|
||||
class UIWindow;
|
||||
class WindowManagerWindows;
|
||||
|
||||
class TextInputSuggestions {
|
||||
public:
|
||||
virtual void Update(const char* text) = 0;
|
||||
|
||||
protected:
|
||||
~TextInputSuggestions() = default;
|
||||
};
|
||||
|
||||
struct TextInputBuffer {
|
||||
std::string& text;
|
||||
int& cursor;
|
||||
int& anchor;
|
||||
std::string& composition;
|
||||
std::string& candidate;
|
||||
int& compositionState;
|
||||
HWND& window;
|
||||
const bool& suggestionsEnabled;
|
||||
UIWindow* const& focused;
|
||||
UIWindow* const& chatInput;
|
||||
const bool& chatOpen;
|
||||
TextInputSuggestions& suggestions;
|
||||
|
||||
void CancelComposition();
|
||||
void DeleteSelection();
|
||||
void Insert(const char* value);
|
||||
void Select(int anchor, int cursor);
|
||||
void CopyDisplayText(std::string& output) const;
|
||||
void Selection(int& anchor, int& cursor) const;
|
||||
|
||||
void SelectionRange(int& begin, int& end) const;
|
||||
|
||||
void RefreshComposition(unsigned codePage);
|
||||
|
||||
void CopySelection(bool password);
|
||||
void Paste(UIWindow* blockedFocus, WindowManagerWindows& windows);
|
||||
|
||||
void MoveBack(unsigned codePage);
|
||||
|
||||
void MoveForward(unsigned codePage);
|
||||
|
||||
void Character(unsigned value, LPARAM unused, unsigned codePage);
|
||||
|
||||
void KeyDown(
|
||||
unsigned key, LPARAM unused, unsigned codePage, bool password, UIWindow* blockedPasteFocus, WindowManagerWindows& windows, UIWindow* const& chatArrows
|
||||
);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
#include "Client/TraditionalKeyInput.h"
|
||||
#include "Client/Input/TraditionalKeyInput.h"
|
||||
#include "Network/TextEncoding.h"
|
||||
#include <windows.h>
|
||||
|
||||
|
|
@ -7,17 +7,16 @@
|
|||
void TraditionalKeyInput::InitializeMappings() {
|
||||
// STATIC: 0x011594E0
|
||||
// GLOBAL: gl_13427
|
||||
static constexpr std::uint8_t bytes[] = {0xA3, 0x74, 0xA3, 0x78, 0xA3, 0xBE, 0xA3, 0xBF, 0xA3, 0xA4, 0xA3, 0xBD,
|
||||
0xA3, 0xBB, 0xA3, 0xAB, 0xA3, 0xAF, 0xA3, 0xB3, 0xA3, 0x76, 0xA3, 0xA7,
|
||||
0xA3, 0x74, 0xA3, 0x74, 0xA3, 0x74, 0xA3, 0xA2, 0xA3, 0xA6, 0xA3, 0xA9,
|
||||
0xA3, 0xAC, 0xA3, 0xB9, 0xA3, 0xAD, 0xA3, 0xB1, 0xA3, 0xAA, 0xA3, 0xBA,
|
||||
0xA3, 0xB0, 0xA3, 0xB4, 0xA3, 0x75, 0xA3, 0xA1, 0xA3, 0x7A, 0xA3, 0xA5,
|
||||
0xA3, 0x74, 0xA3, 0xA3, 0xA3, 0x79, 0xA3, 0x74, 0xA3, 0xA8, 0xA3, 0x77,
|
||||
0xA3, 0xB7, 0xA3, 0xB5, 0xA3, 0xAE, 0xA3, 0xB2, 0xA3, 0xB6};
|
||||
static constexpr std::uint8_t bytes[] = {0xA3, 0x74, 0xA3, 0x78, 0xA3, 0xBE, 0xA3, 0xBF, 0xA3, 0xA4, 0xA3, 0xBD, 0xA3, 0xBB, 0xA3, 0xAB, 0xA3,
|
||||
0xAF, 0xA3, 0xB3, 0xA3, 0x76, 0xA3, 0xA7, 0xA3, 0x74, 0xA3, 0x74, 0xA3, 0x74, 0xA3, 0xA2, 0xA3, 0xA6,
|
||||
0xA3, 0xA9, 0xA3, 0xAC, 0xA3, 0xB9, 0xA3, 0xAD, 0xA3, 0xB1, 0xA3, 0xAA, 0xA3, 0xBA, 0xA3, 0xB0, 0xA3,
|
||||
0xB4, 0xA3, 0x75, 0xA3, 0xA1, 0xA3, 0x7A, 0xA3, 0xA5, 0xA3, 0x74, 0xA3, 0xA3, 0xA3, 0x79, 0xA3, 0x74,
|
||||
0xA3, 0xA8, 0xA3, 0x77, 0xA3, 0xB7, 0xA3, 0xB5, 0xA3, 0xAE, 0xA3, 0xB2, 0xA3, 0xB6};
|
||||
static constexpr char categories[] = "11441443331111111132331233111121111133333";
|
||||
static constexpr unsigned char keys[] = "1234567890ABCDEFGHIJKLNMOPQRSTUVWXYZ\xBD\xBA\xBC\xBE\xBF";
|
||||
|
||||
this->unknown04C1 = 0;
|
||||
|
||||
for (auto& mapping : this->mappings) {
|
||||
mapping.category = 4;
|
||||
}
|
||||
|
|
@ -50,6 +49,7 @@ void TraditionalKeyInput::Key(int virtualKey) {
|
|||
if (!this->keys.empty()) {
|
||||
this->keys.pop_back();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -59,6 +59,7 @@ void TraditionalKeyInput::Key(int virtualKey) {
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
this->keys.push_back(key);
|
||||
}
|
||||
|
||||
|
|
@ -72,6 +73,7 @@ const char* TraditionalKeyInput::DisplayText() const {
|
|||
// FUNCTION: fn_17778
|
||||
const char* TraditionalKeyInput::Display() {
|
||||
char bytes[8] = {};
|
||||
|
||||
for (std::uint8_t key : this->keys) {
|
||||
const auto& mapping = this->mappings[key];
|
||||
if (mapping.category < 4) {
|
||||
|
|
@ -96,6 +98,7 @@ int TraditionalKeyInput::Count() const {
|
|||
if (this->keys.size() == 1 && this->mappings[this->keys.back()].category == 4) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return static_cast<int>(this->keys.size());
|
||||
}
|
||||
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
#ifndef RAGNAROK_SOURCE_CLIENT_TRADITIONALKEYINPUT_H
|
||||
#define RAGNAROK_SOURCE_CLIENT_TRADITIONALKEYINPUT_H
|
||||
#ifndef RAGNAROK_SOURCE_CLIENT_INPUT_TRADITIONALKEYINPUT_H
|
||||
#define RAGNAROK_SOURCE_CLIENT_INPUT_TRADITIONALKEYINPUT_H
|
||||
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
|
|
@ -11,15 +11,12 @@ struct TraditionalKeyMapping {
|
|||
std::uint8_t bytes[3];
|
||||
};
|
||||
|
||||
// Borrowed CLanguageTC fields; not a substitute for its base-language/IME
|
||||
// lifecycle. Key sequence is +0xB8, mappings +0xC0, display +0x58, flag +0x4C1.
|
||||
struct TraditionalKeyInput {
|
||||
std::list<std::uint8_t>& keys;
|
||||
std::array<TraditionalKeyMapping, 256>& mappings;
|
||||
std::string& display;
|
||||
std::uint8_t& unknown04C1;
|
||||
|
||||
// Unmapped byte triples are deliberately untouched; their category becomes 4.
|
||||
void InitializeMappings();
|
||||
void Key(int virtualKey);
|
||||
void DefaultKey(int virtualKey);
|
||||
|
|
@ -1,46 +0,0 @@
|
|||
#include "Client/Launcher.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <windows.h>
|
||||
|
||||
namespace client {
|
||||
|
||||
// OFFSET: 0x00E58820
|
||||
// FUNCTION: fn_24363
|
||||
bool RestartFromCommandLine(char* commandLine) {
|
||||
char* marker = std::strstr(commandLine, "/launcherRESTART:");
|
||||
if (!marker) {
|
||||
return false;
|
||||
}
|
||||
|
||||
STARTUPINFOA startup = {};
|
||||
startup.cb = sizeof(startup);
|
||||
startup.dwFlags = STARTF_USESHOWWINDOW;
|
||||
startup.wShowWindow = SW_SHOWNORMAL;
|
||||
PROCESS_INFORMATION process;
|
||||
// Original behavior ignores CreateProcessA failure and still returns true.
|
||||
CreateProcessA(
|
||||
nullptr, marker + std::strlen("/launcherRESTART:"), nullptr, nullptr, FALSE, 0, nullptr, nullptr, &startup,
|
||||
&process
|
||||
);
|
||||
CloseHandle(process.hProcess);
|
||||
CloseHandle(process.hThread);
|
||||
return true;
|
||||
}
|
||||
|
||||
// OFFSET: 0x00E5D390
|
||||
// FUNCTION: fn_24380
|
||||
void ExitForProtectionCheck(const char* commandLine) {
|
||||
if (std::strstr(commandLine, "/check_themida")) {
|
||||
ExitProcess(0);
|
||||
}
|
||||
}
|
||||
|
||||
// OFFSET: 0x00E5D390
|
||||
// FUNCTION: fn_24380
|
||||
bool AcquireInstanceMutex(HANDLE* mutex) {
|
||||
*mutex = CreateMutexA(nullptr, TRUE, "MutexInit");
|
||||
return GetLastError() != ERROR_ALREADY_EXISTS;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
#ifndef RAGNAROK_SOURCE_CLIENT_LAUNCHER_H
|
||||
#define RAGNAROK_SOURCE_CLIENT_LAUNCHER_H
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
namespace client {
|
||||
|
||||
// Reconstructed semantic name for the original launcher restart branch.
|
||||
// A mutable buffer is required because CreateProcessA may modify its tail.
|
||||
bool RestartFromCommandLine(char* commandLine);
|
||||
|
||||
// Named source extractions of the established WinMain guard blocks.
|
||||
void ExitForProtectionCheck(const char* commandLine);
|
||||
bool AcquireInstanceMutex(HANDLE* mutex);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
#include "Client/ActiveGameMode.h"
|
||||
#include "Client/Mode/ActiveGameMode.h"
|
||||
|
||||
// FUNCTION: fn_17831
|
||||
CGameMode* CWorld::ActiveGameMode() {
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue