Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
559 commits
Select commit Hold shift + click to select a range
678d8e4
Fixed issue with turntable not sync'ing from Host
AMacro Mar 30, 2025
68f37fd
Ready for release
AMacro Mar 30, 2025
9672d0a
Log LiteNetLib Version
AMacro Apr 18, 2025
675c076
Refactor lobby and connection workflow
AMacro Apr 19, 2025
17d2e9e
Add exception for RemoteDispatch
AMacro Apr 19, 2025
e95c08a
Bypass password for friend-only games
AMacro Apr 19, 2025
50b1d30
Improve startup logging
AMacro Apr 19, 2025
e6e87f8
Reverse change to bypass password
AMacro Apr 19, 2025
b430f21
B99.4 Compilation fixes
AMacro Apr 21, 2025
e92a0fd
Fix B99.4 Localisation issues
AMacro Apr 21, 2025
1218324
Logging changes
AMacro Apr 21, 2025
7463198
Change physics Ticks tracking
AMacro Apr 21, 2025
e261bf9
sync full health states
AMacro Jan 28, 2025
8e1ca89
B99.4 Fixes Ready for Release
AMacro Apr 21, 2025
2271bf8
Merge branch 'beta' into feature/self-service
AMacro Apr 21, 2025
ae2e91f
Code and logging cleanup
AMacro Apr 21, 2025
14d8f2c
Create new GridView control
AMacro Apr 25, 2025
d05c610
Update elements for new GridView
AMacro Apr 25, 2025
b80dbd0
Update ServerBrowser to use new GridView
AMacro Apr 25, 2025
86de090
Minor code cleanup for HostGamePane
AMacro Apr 25, 2025
f8acabd
Merge branch 'beta' into feature/self-service
AMacro Apr 25, 2025
31e4799
B99.4 updates
AMacro Apr 26, 2025
6d3624e
Fix null reference issue for clients
AMacro Apr 26, 2025
2b18790
Ready for release
AMacro Apr 27, 2025
df1e1ea
Fixed memory/event subscription leak
AMacro May 4, 2025
6de6773
Start client before resetting states
AMacro May 4, 2025
8d03a43
Fix null reference issues and code tidy up
AMacro May 4, 2025
b651c8a
Additional error handling for null objects
AMacro May 4, 2025
2448fee
Rev up
AMacro May 4, 2025
7ddb233
Fix DVSteamworks for 2025-05-10 updates
AMacro May 10, 2025
b3c99b0
Fix serverGridView placeholder if list is empty
AMacro May 10, 2025
2c9557d
Minor optimisations and code clean-up
AMacro May 10, 2025
1792e70
Add support for chat key binding
AMacro May 10, 2025
7591248
Clean up settings UI tooltips
AMacro May 10, 2025
6f404fe
Add logging for car deletion packets
AMacro May 11, 2025
13fc9ee
Ready for release
AMacro May 11, 2025
ddf9521
Fix bogie issue B99.4 hotfix 2025-05-15
AMacro May 18, 2025
dbe67ce
Ready for release
AMacro May 18, 2025
6e0f85e
Merge branch 'beta' into feature/self-service
AMacro May 18, 2025
3194eae
Fix all players receiving jobs when a new player connects
AMacro May 23, 2025
1411ecf
Fix all players receiving jobs when a new player connects
AMacro May 23, 2025
02b748f
Use static netId allocation for PitStopStations
AMacro May 24, 2025
e781df0
Fix memory leak in client LoadingFinished sub
AMacro May 24, 2025
a87af10
Fix memory leak in client LoadingFinished sub
AMacro May 24, 2025
f18b870
Add cache for future use
AMacro May 24, 2025
a2d0dcc
Use static netId allocation for CashRegisterWithModules
AMacro May 24, 2025
bc2f659
Add RPC timeout calc
AMacro May 25, 2025
bebfc90
Store peer reference in ServerPlayer
AMacro May 25, 2025
f8a7d57
Intercept CashRegisterWithModules interaction
AMacro May 25, 2025
369bb0f
Add CashRegister action packet handling
AMacro May 25, 2025
93d2890
Block pitstop interaction packets from being sent to host
AMacro May 25, 2025
25b0f4c
Fix client not activating objects
AMacro May 25, 2025
ab9ee56
Fix CashRegister SetCash patch
AMacro May 25, 2025
c481b81
Initial commit
AMacro May 30, 2025
a45b699
begin implementation of server API
AMacro May 31, 2025
bce1b4d
Remove redundant comments
AMacro May 31, 2025
1ab8114
Create API test project
AMacro May 31, 2025
8485728
Rework playerId system
AMacro May 31, 2025
3c772b8
Register and deregister Server API Interfaces
AMacro May 31, 2025
8b816e2
Rework IPlayer
AMacro May 31, 2025
de1c215
Add ClientAPI provider
AMacro May 31, 2025
db937db
Update Player connection events
AMacro May 31, 2025
89b6bcf
Implement mod packet system
AMacro May 31, 2025
876d9fa
Implement server mod packet handling
AMacro May 31, 2025
45b646e
Update packet handling
AMacro May 31, 2025
a04d6a7
Implement client packet API
AMacro May 31, 2025
1bb9b1f
Add interfaces for mapping game objects to NetIds
AMacro Jun 1, 2025
ffc61d7
Cleanup
AMacro Jun 1, 2025
d00f269
Add events for server and client creation and destruction
AMacro Jun 1, 2025
27df765
Continue work on Test/Example
AMacro Jun 1, 2025
4cb19d7
Fix issue with service stations not loading
AMacro Jun 1, 2025
17a6018
Fix bulk Pitstop updates
AMacro Jun 1, 2025
04a8d68
Clean up cash register logic
AMacro Jun 1, 2025
564c6b0
Fix loading health state for non-loco TrainCars
AMacro Jun 1, 2025
02b82bc
Complete cash register sync
AMacro Jun 1, 2025
f393768
Track changes to TrainDamage
AMacro Jun 1, 2025
b9c5f1d
Update Logging
AMacro Jun 1, 2025
dfb1d10
Remove unnecessary logging
AMacro Jun 7, 2025
8d6c6c8
Fix issue with DamageController reflection
AMacro Jun 7, 2025
2625bc2
Update interaction workflow
AMacro Jun 7, 2025
94b46fd
Prevent clients calling Cancel() on CashRegisters while loading
AMacro Jun 7, 2025
422a0d9
Add position update to NetworkPluggableObject on drop
AMacro Jun 7, 2025
b923de6
Standardise NetworkedTrainCar.TryGet()
AMacro Jun 7, 2025
00f41ea
Register sync'd objects with NetIdProvider
AMacro Jun 7, 2025
cba11e1
Add framework for chat integration system
AMacro Jun 7, 2025
d4d0aad
Implement chat message callbacks for Server API
AMacro Jun 8, 2025
718c908
Fix packet registration error
AMacro Jun 8, 2025
611d19c
Fix issue with PluggableObjects not syncing correctly on load
AMacro Jun 8, 2025
5673375
Rework NetworkedPitStopStation sync system
AMacro Jun 8, 2025
840b51e
Fix ProcessBulkUpdate() not loading data correctly
AMacro Jun 8, 2025
a288630
Remove LiteNetLib reference from Asset Bundle script
AMacro Jun 12, 2025
c7f8633
Merge branch 'beta' into feature/Mod-API
AMacro Jun 12, 2025
cf5431d
Merge branch 'beta' into feature/self-service
AMacro Jun 12, 2025
de0e0d3
Rework NetIdProvider workflow
AMacro Jun 14, 2025
5ce5794
Rework xPlayerWrappers
AMacro Jun 14, 2025
c347b3d
Rework ChatManager & ServerAPIProvider
AMacro Jun 14, 2025
2a1aa77
Rework ClientAPIProvider
AMacro Jun 14, 2025
b541843
Update MultiplayerAPI Tests
AMacro Jun 14, 2025
91c3385
Refactor Types
AMacro Jun 15, 2025
23eedef
Fix lever blocking
AMacro Jun 15, 2025
e0d2dde
Fix merge error
AMacro Jun 15, 2025
47e4dfc
Change value sync method
AMacro Jun 17, 2025
c864860
Implement mod compatibility identification
AMacro Jun 21, 2025
fe502e4
General cleanup
AMacro Jun 21, 2025
d99fef2
Add translations for chat commands
AMacro Jun 21, 2025
26eeebb
Add translation keys for updates
AMacro Jun 22, 2025
1b46c4b
Add interface for Tick Events
AMacro Jun 22, 2025
e171e7e
Refactor MultiplayerAPITest loading workflow
AMacro Jun 22, 2025
90c19c3
Implement ClientTest
AMacro Jun 22, 2025
d62f235
Add calls to Player events in NetworkServer
AMacro Jun 22, 2025
a1e1442
Ensure Multiplayer registers its own compatibility
AMacro Jun 22, 2025
75d1cdb
Remove errant null check in SendPacketToAll API
AMacro Jun 22, 2025
ff98c24
Add PlayerCount to IClient
AMacro Jun 22, 2025
33ca527
Update IClient.cs
AMacro Jun 22, 2025
8a57d0a
Update documentation
AMacro Jun 22, 2025
11feecc
Refactor and bug fixes for ServerTest chat commands
AMacro Jun 22, 2025
c1a0676
Ready for testing and release
AMacro Jun 22, 2025
f3e1c9d
Fix bulk sync and car selection changes
AMacro Jun 22, 2025
0fbdea9
Fix pitstop pluggable object sync
AMacro Jun 22, 2025
c3b8414
Remove excessive logging
AMacro Jun 22, 2025
bfd14d0
Loading machine
Chump-the-Lump Jun 23, 2025
a8852c7
WHY DID GITHUB LEAVE THE MEGE CONFLICTS IN THE FUCKING FILE
Chump-the-Lump Jun 23, 2025
849f0b3
Add PlayerDistanceGameObjectsDisablerPatch from feature/self-service
AMacro Jun 24, 2025
142e848
Add '*_office_anchor' objects to PlayerDistanceGameObjectsDisabler Patch
AMacro Jun 24, 2025
c712fd3
Squashed commit of the following:
AMacro Jun 24, 2025
3f4c91a
Refactored JobData
AMacro Jun 28, 2025
813698e
Ensure job started correctly
AMacro Jun 28, 2025
d2d1ba3
Extend NetworkedWarehouseMachineController
AMacro Jun 28, 2025
af190c3
Refactor to use NetworkedWarehouseMachineController NetIds
AMacro Jun 28, 2025
6c1507c
Make loading and unloading server authoratative
AMacro Jun 28, 2025
9f40120
Merge pull request #110 from Chump-the-Lump/alpha
AMacro Jun 28, 2025
37fc8ac
Ready for release
AMacro Jun 28, 2025
5e9fa78
Merge branch 'beta' into feature/self-service
AMacro Jun 28, 2025
9782374
Change BlockInput to prevent disabling Manual Service
AMacro Jun 29, 2025
db1d634
Improve culling algorithm
AMacro Jun 29, 2025
8dce628
Implement a generic CullingManager
AMacro Jul 5, 2025
8d8b4b9
Refactor to use Culling Manager
AMacro Jul 7, 2025
7b16d21
Rework PluggableObject workflow
AMacro Jul 7, 2025
716de8d
General cleanup
AMacro Jul 7, 2025
9d2bbf6
Change to StartSnappingTo
AMacro Jul 7, 2025
2b3eb90
Update API documentation
AMacro Jul 13, 2025
e68bc34
Fix update localisation issue
AMacro Jul 13, 2025
2ff90c5
Fix compatibility with B99.6
AMacro Jul 18, 2025
683966b
Fix compatibility with B99.6
AMacro Jul 18, 2025
82eeae7
Ready for release 0.1.12.2
AMacro Jul 18, 2025
80d8f3f
Add API version support
AMacro Jul 19, 2025
ed43ffa
Refactor paint theme system to use uint theme IDs
AMacro Jul 19, 2025
06ee5dc
Fix compatibility with B99.6
AMacro Jul 20, 2025
3960533
Fix faucet positioning
AMacro Jul 29, 2025
8e0f140
Rework PaintThemeLookup
AMacro Jul 29, 2025
67f6d6b
Fix issue with clients clearing cash registers
AMacro Aug 10, 2025
821f6cc
Rework BulkUpdate processing
AMacro Aug 10, 2025
0503475
Fix issue with colliders being optimised out
AMacro Aug 10, 2025
a4ce3b3
Minor clean up of namespace
AMacro Aug 16, 2025
6955748
Refactor CashRegister*Patch
AMacro Aug 23, 2025
6947360
Block ReturnMoneyToPlayerCheck
AMacro Aug 23, 2025
c8a5910
Ignore shop cash registers
AMacro Aug 23, 2025
a9fa369
Add rejection types and fix logging
AMacro Aug 23, 2025
b1400de
Fix resource sync issues
AMacro Aug 23, 2025
d48d5a3
minor clean up
AMacro Aug 23, 2025
292a477
Ready for alpha testing
AMacro Aug 23, 2025
1014c0a
Merge branch 'feature/self-service' into alpha
AMacro Aug 23, 2025
06a9632
Refactor to use BinaryWriter/Reader and move base to MultiplayerAPI
AMacro Aug 23, 2025
3aea969
Expose registration of custom task serialiser and deserialiser
AMacro Aug 23, 2025
721c4a9
Add documentation for TaskNetworkData
AMacro Aug 24, 2025
0fb30e5
Add auto compression to ExternalSerializablePacketWrapper
AMacro Aug 29, 2025
2bf1638
fix possible null reference issues
AMacro Aug 29, 2025
3706c6e
Add ColorSerializer for Unity.Color
AMacro Aug 30, 2025
6e772f8
Add Vector3 and Quaternion serialisation and XML docs
AMacro Aug 30, 2025
4d2f902
Fix incorrect IsHost() in ServerPlayerWrapper
AMacro Aug 30, 2025
9fb28f3
Refactor use of player.Id and peer.id
AMacro Sep 2, 2025
49abc4c
Add PlayerId property to IClient and ClientAPIProvider
AMacro Sep 2, 2025
481facc
Move player connected event to post-authentication
AMacro Sep 6, 2025
3cf7cfd
Merge branch 'beta' into feature/Mod-API
AMacro Sep 6, 2025
a2d518a
Add periodic weather state updates to fix time drift
AMacro Sep 13, 2025
e8cf951
Add time limit and last task support to task sync
AMacro Sep 13, 2025
9e8aaf5
Ensure jobs are loaded prior to taking
AMacro Sep 13, 2025
0349dbe
Implement job task synchronisation
AMacro Sep 14, 2025
271c233
Reorder job time updates in job sync loop
AMacro Sep 14, 2025
7fa28e6
Sync JobManager time in save game data packets
AMacro Sep 14, 2025
894d565
Refactor warehouse machine and cargo state sync
AMacro Sep 14, 2025
6ee1a68
Remove unused GetFromWarehouseMachineController method
AMacro Sep 14, 2025
b05bfea
Add compatibility status for three new mods
AMacro Sep 14, 2025
5806f25
Refactor warehouse machine lookup in cargo state handler
AMacro Sep 14, 2025
8f6ae04
Add mod-controlled ready-block system to client
AMacro Oct 12, 2025
ec5a293
Refactor task networking to use NetworkedTask
AMacro Oct 12, 2025
e42d201
Add WarehouseMachineLookup for improved net ID handling
AMacro Oct 12, 2025
45c5b68
Fix password check in server browser
AMacro Oct 24, 2025
19f8284
Stop sync of TrainCar rotation while railed
AMacro Oct 24, 2025
3c67383
Refactor for future dedicated server
AMacro Oct 24, 2025
bf50aa6
Add excludeSelf option to packet broadcast methods
AMacro Oct 25, 2025
808a9af
Code cleanup and doc improvements
AMacro Oct 25, 2025
b5c5e02
Improve job validation response waiting logic
AMacro Oct 25, 2025
7eaa8da
Update mod compatibility and patch WarehouseMachineController
AMacro Nov 7, 2025
9a164eb
Refactor task network data registration and conversion
AMacro Nov 8, 2025
f045b7a
Improve XML documentation for API interfaces
AMacro Nov 8, 2025
2122c06
Add Car support to NetIdProvider and NetworkedTrainCar
AMacro Nov 8, 2025
d6eabd7
Add script to convert docs for GitHub Wiki
AMacro Nov 8, 2025
f7333d2
Add debug patch checking and bump version to 0.1.12.9
AMacro Nov 9, 2025
9659a22
Merge branch 'feature/Mod-API' into alpha
AMacro Nov 9, 2025
f82239e
Refactor player identification to use PlayerId property
AMacro Nov 9, 2025
a44b1f8
Refactor Fnv1aHash to StringHashing utility class
AMacro Nov 15, 2025
9f1ad26
Add CargoTypeLookup for networked cargo type mapping
AMacro Nov 15, 2025
f42fca9
Refactor cargo type serialization to use net IDs
AMacro Nov 15, 2025
50c3c71
Add support for uint NetId in network API
AMacro Nov 15, 2025
1ad188c
Delay job manager time load until logic controller init
AMacro Nov 15, 2025
bd33346
Fix player rotation handling on vehicles for VR players
AMacro Nov 22, 2025
3cb0590
Fix edge case where car is unintentionally deleted
AMacro Nov 22, 2025
9fd3cc5
Replace GrabHandlerGizmoItem with CustomNonVrGrabAnchor
AMacro Nov 22, 2025
c248555
Add null check in TryGetNetId for CargoType_v2
AMacro Nov 22, 2025
e4af9cb
Skip item anchor offset capture in VR mode
AMacro Nov 22, 2025
6d1db35
Fix issue where pitstop can not be initialised on clients
AMacro Nov 22, 2025
7bc6588
Initialise itemAnchorOffset with default values
AMacro Nov 22, 2025
6a18733
Fix issues with NetworkedPitStopStation in VR
AMacro Nov 22, 2025
7a844fd
Refactor train coal/firebox networking
AMacro Nov 22, 2025
4e7272f
Comment out debug logging in networking and patch files
AMacro Nov 22, 2025
c384f63
Refactor train port and fuse IDs to use uint
AMacro Nov 22, 2025
dc70e3b
Refactor task state update logic to reduce spamming
AMacro Nov 23, 2025
8d27565
Add train control authority request and update system
AMacro Nov 23, 2025
310c4c1
Refactor PaintTheme registration and lookup API
AMacro Nov 29, 2025
7f4f5c8
Improve cargo type registration and logging
AMacro Nov 29, 2025
eaab4cf
Fix VR check logic in item anchor offset capture
AMacro Nov 29, 2025
b33b76b
Add paint theme change validation and syncing
AMacro Nov 29, 2025
1845650
Refactor pit stop interaction packet type to enum
AMacro Nov 29, 2025
23d3c6d
Add mod compatibility and silence cargo type log
AMacro Nov 29, 2025
1b44a8e
Add compatibility for dv_f_spammer mod
AMacro Nov 29, 2025
6b5b4ea
Update to Multiplayer API v1.0.0.0 and mod version 0.1.13.0
AMacro Nov 29, 2025
17033f3
Update .gitattributes for line ending normalization
AMacro Nov 30, 2025
e6fa62f
Add sync for generic switches
AMacro Dec 7, 2025
791ff7e
Optimise TrainCar position updates
AMacro Dec 9, 2025
e49c8e4
Fix issue with cut-out not syncing after repair
AMacro Dec 18, 2025
5a590e7
Additional null checks
AMacro Dec 18, 2025
3788166
Fix pointset traveller spam
AMacro Dec 18, 2025
7fe0529
Fix issues with cash register stealing cash
AMacro Dec 18, 2025
2daa053
Refactor pit stop station networking and add tick to packets
AMacro Dec 18, 2025
293fa60
Ensure player objects are cleaned up
AMacro Dec 18, 2025
3f56920
Ready for release 0.1.13.4
AMacro Dec 18, 2025
5a9d440
Enhance mod requirements in server browser UI
AMacro Dec 24, 2025
345416b
Update build version check to use MenuProvider
AMacro Dec 24, 2025
a7d9d7a
Refactor LobbyServerData 'required mods' to use ModInfo[] instead of …
AMacro Jan 1, 2026
aeccba0
Improve lobby data handling for ModInfo
AMacro Jan 4, 2026
0911be5
Change handling of incompatible mods in compatibility manager
AMacro Jan 4, 2026
0596db9
Publicise `DV.UIFramework.CollapsibleElement`
AMacro Jan 4, 2026
ba46faf
Use collapsible elements for mod details
AMacro Jan 4, 2026
e5775ed
Refactor server details and mods UI in ServerBrowserPane
AMacro Jan 4, 2026
604be52
Improve localisation for server browser and disconnect reasons
AMacro Jan 8, 2026
4bba744
Remove duplicate host details label in server info
AMacro Jan 8, 2026
3a80a19
Fix issue preventing player markers from being hidden
AMacro Jan 8, 2026
0a9bbbf
Ready for release 0.1.13.5
AMacro Jan 8, 2026
06c5110
Remove over the top logging
AMacro Jan 10, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
10 changes: 9 additions & 1 deletion .gitattributes
Original file line number Diff line number Diff line change
@@ -1 +1,9 @@
* text=auto eol=lf
# Set default behavior to automatically normalize line endings
* text=auto

# Force CRLF line endings for C# files
*.cs text eol=crlf

# Force CRLF for other common Windows development files (optional)
*.csproj text eol=crlf
*.sln text eol=crlf
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -306,3 +306,6 @@ MultiplayerAssets/ProjectSettings/*
!MultiplayerAssets/ProjectSettings/ProjectVersion.txt
# Packages
!MultiplayerAssets/Packages
/Lobby Servers/Rust Server/target
*.pem
/docs
348 changes: 348 additions & 0 deletions Convert-ToGitHubWiki.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,348 @@
param(
[Parameter(Mandatory=$false)]
[string]$InputPath = ".",

[Parameter(Mandatory=$false)]
[string]$OutputPath = "./wiki-output",

[Parameter(Mandatory=$false)]
[switch]$Flatten,

[Parameter(Mandatory=$false)]
[switch]$InPlace
)

<#
.SYNOPSIS
Converts XMLDoc2Markdown output to GitHub Wiki compatible format.

.DESCRIPTION
This script processes markdown files generated by XMLDoc2Markdown and converts them
to be compatible with GitHub Wiki by:
- Removing .md extensions from links
- Removing ./ prefixes from links
- Optionally flattening all files into a single markdown file
- Optionally modifying files in place

.NOTES
Created with assistance from GitHub Copilot

.PARAMETER InputPath
The path to the directory containing the markdown files. Default is current directory.

.PARAMETER OutputPath
The path where converted files will be saved. Default is ./wiki-output.
Ignored if -InPlace is used.

.PARAMETER Flatten
If specified, all markdown files will be combined into a single file.

.PARAMETER InPlace
If specified, modifies files in place instead of creating copies.

.EXAMPLE
.\Convert-ToGitHubWiki.ps1
Converts all markdown files in current directory to wiki-output folder.

.EXAMPLE
.\Convert-ToGitHubWiki.ps1 -InPlace
Modifies all markdown files in place.

.EXAMPLE
.\Convert-ToGitHubWiki.ps1 -Flatten -OutputPath "./wiki.md"
Combines all markdown files into a single wiki.md file.
#>

function Convert-MarkdownLinks {
param(
[string]$Content,
[bool]$UseAnchors = $false
)

if ($UseAnchors) {
# Convert relative links to anchor links for flattened output
# Match patterns like [Text](./path/file.md) or [Text](path/file.md)
$Content = [regex]::Replace($Content, '\[([^\]]+)\]\(\.?/?([^)]+?)(?:\.md)?\)', {
param($match)
$linkText = $match.Groups[1].Value
$linkPath = $match.Groups[2].Value

# Skip external links (http/https)
if ($linkPath -match '^https?://') {
return $match.Value
}

# Convert path to anchor
# Remove path separators and convert to lowercase
$anchor = $linkPath -replace '[/\\]', '-' -replace '[^a-zA-Z0-9\s-]', '' -replace '\s+', '-' -replace '-+', '-'
$anchor = $anchor.ToLower().Trim('-')

return "[$linkText](#$anchor)"
})
} else {
# For GitHub Wiki: Convert links to use only filename (no directory path)
# Match patterns like [Text](./path/to/file.md) or [Text](path/to/file.md#anchor)
$Content = [regex]::Replace($Content, '\[([^\]]+)\]\(\.?/?([^)#]+?)(?:\.md)?(#[^)]+)?\)', {
param($match)
$linkText = $match.Groups[1].Value
$linkPath = $match.Groups[2].Value
$anchor = $match.Groups[3].Value

# Skip external links (http/https)
if ($linkPath -match '^https?://') {
return $match.Value
}

# Extract just the filename from the path (remove directory)
$filename = Split-Path -Path $linkPath -Leaf

# Return with just filename and optional anchor
return "[$linkText]($filename$anchor)"
})
}

return $Content
}

function Get-MarkdownFiles {
param(
[string]$Path,
[string]$ExcludePath = $null,
[switch]$ExcludeIndex
)

$files = Get-ChildItem -Path $Path -Filter "*.md" -Recurse | Where-Object { $_.Name -ne "README.md" }

# Exclude index.md if requested (for flattened output which generates its own TOC)
if ($ExcludeIndex) {
$files = $files | Where-Object { $_.Name -ne "index.md" }
}

# Exclude files in the output directory
if ($ExcludePath) {
$excludeFullPath = (Resolve-Path -Path $ExcludePath -ErrorAction SilentlyContinue)
if ($excludeFullPath) {
$files = $files | Where-Object { !$_.FullName.StartsWith($excludeFullPath) }
}
}

return $files
}

function Flatten-ToSingleFile {
param(
[string]$InputPath,
[string]$OutputFile
)

Write-Host "Flattening markdown files into single document..." -ForegroundColor Cyan

# Get output directory to exclude it from processing
$outputDir = Split-Path -Path $OutputFile -Parent
if ($outputDir) {
$outputDir = Join-Path -Path $InputPath -ChildPath $outputDir
}

$files = Get-MarkdownFiles -Path $InputPath -ExcludePath $outputDir -ExcludeIndex | Sort-Object FullName

$combinedContent = @()

# Build mapping of file paths to their heading anchors (filename -> heading anchor)
$fileToAnchor = @{}

foreach ($file in $files) {
$relativePath = $file.FullName.Substring($InputPath.Length).TrimStart('\', '/')
$content = Get-Content -Path $file.FullName -Raw -Encoding UTF8

# Extract first heading
if ($content -match '^#\s+(.+)') {
$heading = $matches[1].Trim()
$anchor = $heading -replace '[^a-zA-Z0-9\s-]', '' -replace '\s+', '-' -replace '-+', '-'
$anchor = $anchor.ToLower().Trim('-')

# Store mapping: filename (without extension) -> anchor
$filename = [System.IO.Path]::GetFileNameWithoutExtension($file.Name)
$fileToAnchor[$filename.ToLower()] = $anchor

# Also store full relative path mapping (with forward slashes, no extension)
$pathWithoutExt = $relativePath -replace '\.md$', '' -replace '\\', '/'
$fileToAnchor[$pathWithoutExt.ToLower()] = $anchor
}
}

# Add table of contents header
$combinedContent += "## Table of Contents"
$combinedContent += ""

# Build hierarchical TOC based on namespace from files
$tocStructure = @{}

foreach ($file in $files) {
$relativePath = $file.FullName.Substring($InputPath.Length).TrimStart('\', '/')
$content = Get-Content -Path $file.FullName -Raw -Encoding UTF8

# Extract first heading and namespace
$heading = $null
$namespace = $null

if ($content -match '^#\s+(.+)') {
$heading = $matches[1].Trim()
}

if ($content -match 'Namespace:\s*([^\r\n]+)') {
$namespace = $matches[1].Trim()
}

if ($heading) {
$anchor = $heading -replace '[^a-zA-Z0-9\s-]', '' -replace '\s+', '-' -replace '-+', '-'
$anchor = $anchor.ToLower().Trim('-')

# Use namespace if available, otherwise use root
$category = if ($namespace) { $namespace } else { '_root' }

if (!$tocStructure.ContainsKey($category)) {
$tocStructure[$category] = @()
}
$tocStructure[$category] += @{ Heading = $heading; Anchor = $anchor }
}
}

# Output TOC with sections
$orderedCategories = $tocStructure.Keys | Sort-Object | Where-Object { $_ -ne '_root' }

# Root items first if any
if ($tocStructure.ContainsKey('_root')) {
foreach ($item in $tocStructure['_root']) {
$combinedContent += "- [$($item.Heading)](#$($item.Anchor))"
}
$combinedContent += ""
}

# Then categorized items
foreach ($category in $orderedCategories) {
$combinedContent += "### $category"
$combinedContent += ""
foreach ($item in $tocStructure[$category]) {
$combinedContent += "- [$($item.Heading)](#$($item.Anchor))"
}
$combinedContent += ""
}

$combinedContent += "---"
$combinedContent += "<br></br>"
$combinedContent += ""

# Add content from each file
foreach ($file in $files) {
$relativePath = $file.FullName.Substring($InputPath.Length).TrimStart('\', '/')
Write-Host " Processing: $relativePath"

$content = Get-Content -Path $file.FullName -Raw -Encoding UTF8

# Convert links by replacing each known path with its anchor
foreach ($path in $fileToAnchor.Keys) {
$anchor = $fileToAnchor[$path]
$escapedPath = [regex]::Escape($path)
# Replace links like [Text](path) with [Text](#anchor)
$content = $content -replace "\]\($escapedPath\)", "](#$anchor)"
# Also handle links with existing fragment anchors - preserve the fragment
# but this is tricky, so for now just do the simple case
}

# Add source file comment
$combinedContent += "<!-- Source: $relativePath -->"
$combinedContent += ""

# Add content
$combinedContent += $content.TrimEnd()
$combinedContent += ""
$combinedContent += "---"
$combinedContent += "<br></br>"
$combinedContent += ""
}

# Ensure output directory exists
if ($outputDir -and !(Test-Path -Path $outputDir)) {
New-Item -Path $outputDir -ItemType Directory -Force | Out-Null
}

# Write combined file
$combinedContent -join "`n" | Set-Content -Path $OutputFile -Encoding UTF8 -NoNewline

Write-Host "Created flattened file: $OutputFile" -ForegroundColor Green
Write-Host "Processed $($files.Count) files" -ForegroundColor Green
}

function Convert-Files {
param(
[string]$InputPath,
[string]$OutputPath,
[bool]$InPlace
)

Write-Host "Converting markdown files for GitHub Wiki..." -ForegroundColor Cyan

$files = Get-MarkdownFiles -Path $InputPath
$count = 0

foreach ($file in $files) {
$relativePath = $file.FullName.Substring($InputPath.Length).TrimStart('\', '/')
Write-Host " Processing: $relativePath"

$content = Get-Content -Path $file.FullName -Raw -Encoding UTF8
$convertedContent = Convert-MarkdownLinks -Content $content

if ($InPlace) {
$outputFile = $file.FullName
} else {
$outputFile = Join-Path -Path $OutputPath -ChildPath $relativePath
$outputDir = Split-Path -Path $outputFile -Parent

if (!(Test-Path -Path $outputDir)) {
New-Item -Path $outputDir -ItemType Directory -Force | Out-Null
}
}

$convertedContent | Set-Content -Path $outputFile -Encoding UTF8 -NoNewline
$count++
}

if ($InPlace) {
Write-Host "Modified $count files in place" -ForegroundColor Green
} else {
Write-Host "Converted $count files to: $OutputPath" -ForegroundColor Green
}
}

# Main execution
try {
# Resolve full path
$InputPath = Resolve-Path -Path $InputPath -ErrorAction Stop

if ($Flatten) {
# Determine output file path
if ($OutputPath -like "*.md") {
$flattenedFile = $OutputPath
} else {
$flattenedFile = Join-Path -Path $OutputPath -ChildPath "API-Documentation.md"
}

Flatten-ToSingleFile -InputPath $InputPath -OutputFile $flattenedFile
} else {
if ($InPlace) {
$confirmation = Read-Host "This will modify files in place. Continue? (y/n)"
if ($confirmation -ne 'y') {
Write-Host "Operation cancelled." -ForegroundColor Yellow
exit
}
}

Convert-Files -InputPath $InputPath -OutputPath $OutputPath -InPlace $InPlace
}

Write-Host "`nConversion complete!" -ForegroundColor Green

} catch {
Write-Host "Error: $_" -ForegroundColor Red
exit 1
}
25 changes: 25 additions & 0 deletions Directory.Build.targets.EXAMPLE
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<!--
Update DvInstallDir and UnityInstallDir paths to your local install directories
Do not use trailing slashes

If using code signing:
Update SignToolPath to the directory of signtool.exe
Update Cert-Thumb to the thumbprint of your code signing certificate, otherwise leave blank

Save this updated file as 'Directory.Build.targets'

-->
<Project>
<PropertyGroup>
<DvInstallDir>C:\Program Files (x86)\Steam\steamapps\common\Derail Valley</DvInstallDir>
<UnityInstallDir>C:\Program Files\Unity\Hub\Editor\2019.4.40f1\Editor</UnityInstallDir>
<ReferencePath>
$(DvInstallDir)\DerailValley_Data\Managed\;
$(DvInstallDir)\DerailValley_Data\Managed\UnityModManager\;
$(UnityInstallDir)\Data\Managed\
</ReferencePath>
<AssemblySearchPaths>$(AssemblySearchPaths);$(ReferencePath);</AssemblySearchPaths>
<SignToolPath>C:\Program Files (x86)\Microsoft SDKs\ClickOnce\SignTool\</SignToolPath>
<Cert-Thumb>7cf2b8a98a09ffd407ada2e94f200af24a0e68bc</Cert-Thumb>
</PropertyGroup>
</Project>
Loading