CS2 MacOS+Whisky 1.2.3f1

Question/Discussion

Hey everyone. I think i managed to launch the latest version of the game (1.2.3f1) on MacOS via Whisky. I followed the basic Whisky instructions to install the game (well, install the game + apply dotnet48 and win10 winetricks).

The fix itself

https://preview.redd.it/0ownq4hl7vle1.png?width=3456&format=png&auto=webp&s=39dd062320faf72c565f8fdce36093ae62991872

The fix itself is relatively simple and consists of two steps. You may try to launch the game without following step 2, it may work.

  1. Replace original Colossal.IO.dll with patched version. This DLL is located in <GAME_FOLDER>/Cities2_Data/Managed folder, GAME_FOLDER is where your game is located. You can get the patched DLL on my Github or patch it yourself following my explanation below.
  2. Remove any .DS_STORE files from <GAME_FOLDER> and its subfolders (where your game is located). .DS_STORE is a special invisible MacOS file related to Finder, it may be present in any folders which were opened by Finder. Basically when the game loads its assets it makes some use of the combined hash of all files in Cities2_Data/Content folders, .DS_STORE presence changes the resulting hash, ruining the loading process. The best way to make sure no .DS_STORE is present is to execute the following bash command inside game's folder: find . -name '.DS_Store' -type f -delete. If you are unfamiliar with Bash, you should basically select drag-and-drop the game's folder onto the Terminal app in the Dock (not in the Terminal's window itself, but in the Dock), paste this command and press enter.

If you did everything right, the game will launch successfully.

However, there are some limitations:

  • You must repeat the process every time after updating/reinstalling the game.
  • Mods do not work due to some other error, maybe I will fix it later.

Some technical details

The process of solving the game's crash is somewhat straightforward: check the Player.log for errors, examine the code/add tons of prints/exception info to the corresponding DLL (obvious which one from logs), find a bypass, rinse and repeat.

Experimenting with CS2's DLLs is surprisingly simple as it is written in C# which allows to decompile the DLL directly into the source code. Personally, I like the dnSpy tool (https://github.com/dnSpyEx/dnSpy) - somewhat discontinued, but works exceptionally well. dnSpy provides a neat way to view the source code in VSCode-like editor, plus it allows to edit individual C# classes/functions and recompile the necessary parts of the DLL in one click. The worst part is it is only available on Windows (and Whisky cannot launch it either as it is a WPF app), but you can use Parallels or VMWare Fusion to overcome this.

When I first examined Player.log I have seen these lines:

[Steamworks] [ERROR]   System.IO.IOException
  at System.IO.LongDirectory+<EnumerateFileSystemIterator>d__14.MoveNext () [0x00138] in <582118ee79374f13aec42c6d75dc556c>:0 
  at Colossal.PSI.Common.ContentHelper.ListContent (System.Collections.Generic.IReadOnlyList`1[System.ValueTuple`2[System.String,System.String]]& aggregatedContents, System.Collections.Generic.IReadOnlyList`1[System.ValueTuple`2[System.String,System.String]]& discardedContents) [0x00057] in <7c1db256ac4e498c94dcc586afcdbb59>:0 
  at Colossal.PSI.Common.DlcHelper.GetDlcAttributes () [0x00044] in <7c1db256ac4e498c94dcc586afcdbb59>:0 
  at Colossal.PSI.Steamworks.SteamworksPlatform.RemapDLCs () [0x00058] in <335585a4369e41f7979777c450d71026>:0 
  at Colossal.PSI.Steamworks.SteamworksPlatform.Initialize () [0x000e0] in <335585a4369e41f7979777c450d71026>:0 

When I loaded the Colossal.PSI.Common DLL into the dnSpy it became somewhat obvious that problem lies in the Colossal.IO.dll. I tweaked LongDirectory.EnumerateFileSystemIterator function a bit to include the Win32 API error code in the error message, and the error codes did not make any sense and were random each launch. When I set WINEDEBUG=+file for Cities2.exe and examined Wine debug logs, I found nothing suspicious and it seemed like the app can successfully read files in the folder.

So I decided to just remove the error check inside EnumerateFileSystemIterator and EnumerateFileSystemIteratorRecursive functions and see what happened. Surprisingly it solved the error :)

https://preview.redd.it/g2fjij40gvle1.png?width=1308&format=png&auto=webp&s=df95a885e14fea7cbbfe803658eddcb41f60957b

To me there it seems like some kind of bug in Wine, which breaks the error handling of Win32 API methods, but I did not manage to dig deeper into this matter.

If anyone here knows is somewhat related to coding, you can follow my steps and try to fix the modding error, it seems like just another shitty I/O error.

Posted Feb 28, 2025, 12:33 PM UTC

206
Loading comments…