Skip to content

Commit 80e824c

Browse files
committed
adding linux client support
1 parent f409568 commit 80e824c

4 files changed

Lines changed: 74 additions & 16 deletions

File tree

README.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,27 @@
66
**Current status:** Available for early testing.<br>
77

88
## Download & Installation
9+
### Windows
910
If you have already installed the Addons, make sure to run file verification through Steam before installing a new version (go to Steam, click RMB on the game, open **Properties**, go to **Local Files** and click on **Verify integrity of game files...**)!
1011

1112
Go to [Releases](https://github.com/Erdroy/Stationeers.Addons/releases), select latest release and download zip file named 'Stationeers.Addons-vX.X-X.zip'. Now go to Steam, click RMB on the game, open **Properties**, go to **Local Files** and click on **BROWSE LOCAL FILES**. It should open new window for you. Next, you have to open the downloaded zip and drag all of its contents into the game folder (`AddonManager` folder and `version.dll`). And that's it! Enjoy your mods!
1213

1314
***Note:** After you've subscribed to an addon on the workshop, you have to restart the game. This will be improved in the future.*
1415

16+
### Linux (client, not tested for servers)
17+
*(this is in beta, might not work)*
18+
Installing:
19+
1) Do the same unzipping as in windows (extract all zip content on the game installation root folder)
20+
2) In a shell, navigate to the Addons folder you've just extracted
21+
3) Run `mono Stationeers.Addons.Patcher.exe`
22+
4) Enjoy (hopefully)
23+
24+
Updating:
25+
1) Like in windows, verify the files from steam
26+
2) Extract new version of this package
27+
3) Run the exe (step 3 of `Installing`)
28+
29+
1530
## Links
1631
* [Discord](https://discord.gg/b6kFrUATdm)
1732
* [Trello](https://trello.com/b/zSHKh2XO/stationeersaddons)

Source/Stationeers.Addons.Patcher/Core/Patchers/MonoPatcher.cs

Lines changed: 53 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ public class MonoPatcher : IGamePatcher
2828
private AssemblyDefinition _assembly;
2929
private ModuleDefinition _module;
3030
private TypeDefinition _type;
31+
private string _installResourcesDir;
3132

3233
public string AssemblyFileName;
3334
public string TemporaryAssemblyFileName;
@@ -39,7 +40,7 @@ public void Load(string instanceExe)
3940

4041
if (!File.Exists(AssemblyFileName))
4142
Logger.Current.LogFatal($"Could not find game/server assembly '{AssemblyFileName}'.");
42-
43+
4344
// Copy the assembly into temporary file
4445
File.Copy(AssemblyFileName, TemporaryAssemblyFileName, true);
4546

@@ -101,6 +102,9 @@ public void Patch()
101102
// Backup the assembly first
102103
Backup();
103104

105+
// Copy dlls to the Managed folder, required for linux to be auto loaded
106+
CopyRequiredAssemblies();
107+
104108
// We are clear here, go ahead and patch the game
105109
Inject();
106110
}
@@ -121,14 +125,13 @@ public bool IsPatched()
121125
private void GetInstanceAssemblies(string installInstance)
122126
{
123127
// This is kind of verbose, might need to be rewritten in a more concise manner
124-
string installResourcesDir = null;
125-
if(installInstance == Constants.GameExe)
128+
if (installInstance == Constants.GameExe)
126129
{
127-
installResourcesDir = Constants.GameResourcesDir;
130+
_installResourcesDir = Constants.GameResourcesDir;
128131
}
129-
else if(installInstance == Constants.ServerExe)
132+
else if (installInstance == Constants.ServerExe)
130133
{
131-
installResourcesDir = Constants.ServerResourcesDir;
134+
_installResourcesDir = Constants.ServerResourcesDir;
132135
}
133136
System.Diagnostics.Debug.Assert(!string.IsNullOrEmpty(installResourcesDir), "Invalid install dir!");
134137

@@ -210,6 +213,15 @@ private void CreateLoaderMethodBody(ref ILProcessor processor, ref MethodDefinit
210213
typeof(Type)
211214
}));
212215

216+
// Get Environment.CurrentDirectory in the runtime
217+
var curDir = _module.ImportReference(typeof(Environment).GetMethod("get_CurrentDirectory"));
218+
// Path combine for joining the assembly full path
219+
var pathCombine = _module.ImportReference(typeof(Path).GetMethod("Combine", new[]
220+
{
221+
typeof(string),
222+
typeof(string)
223+
}));
224+
213225
var invokeMember = _module.ImportReference(typeof(Type).GetMethod("InvokeMember", new[]
214226
{
215227
typeof(string),
@@ -226,8 +238,11 @@ private void CreateLoaderMethodBody(ref ILProcessor processor, ref MethodDefinit
226238
method.Body.Variables.Add(new VariableDefinition(_module.ImportReference(typeof(object))));
227239

228240
// Create instructions
229-
processor.Append(processor.Create(OpCodes.Ldstr, Constants.LoaderAssemblyFileName));
230-
processor.Append(processor.Create(OpCodes.Call, loadFile));
241+
processor.Append(processor.Create(OpCodes.Nop));
242+
processor.Append(processor.Create(OpCodes.Call, curDir)); // load current dir
243+
processor.Append(processor.Create(OpCodes.Ldstr, Constants.LoaderAssemblyFileName)); // load assembly path
244+
processor.Append(processor.Create(OpCodes.Call, pathCombine)); // call Path.Combine
245+
processor.Append(processor.Create(OpCodes.Call, loadFile)); // call Assembly.LoadFile(resultingPath)
231246

232247
processor.Append(processor.Create(OpCodes.Ldstr, Constants.LoaderTypeName));
233248
processor.Append(processor.Create(OpCodes.Callvirt, getType));
@@ -239,7 +254,7 @@ private void CreateLoaderMethodBody(ref ILProcessor processor, ref MethodDefinit
239254
processor.Append(processor.Create(OpCodes.Ldloc_0));
240255

241256
processor.Append(processor.Create(OpCodes.Ldstr, Constants.LoaderFunctionName));
242-
processor.Append(processor.Create(OpCodes.Ldc_I4, (int) BindingFlags.InvokeMethod));
257+
processor.Append(processor.Create(OpCodes.Ldc_I4, (int)BindingFlags.InvokeMethod));
243258

244259
processor.Append(processor.Create(OpCodes.Ldnull));
245260
processor.Append(processor.Create(OpCodes.Ldloc_1));
@@ -250,5 +265,33 @@ private void CreateLoaderMethodBody(ref ILProcessor processor, ref MethodDefinit
250265
processor.Append(processor.Create(OpCodes.Pop));
251266
processor.Append(processor.Create(OpCodes.Ret));
252267
}
268+
269+
private void CopyRequiredAssemblies()
270+
{
271+
// This was taken from Stationeers.Addons csproj
272+
// Perhaps it could be "cecilled" in a PreBuild Script?
273+
// Copies required runtime assemblies to the Managed folder which seems to load them
274+
// (without doing this, you get filenotfoundexceptions in the game runtime console for 0harmony, etc)
275+
var assemblies = new[]
276+
{
277+
"0Harmony",
278+
"Microsoft.CodeAnalysis",
279+
"Microsoft.CodeAnalysis.CSharp",
280+
"System.Buffers",
281+
"System.Collections.Immutable",
282+
"System.Memory",
283+
"System.Numerics.Vectors",
284+
"System.Reflection.Metadata",
285+
"System.Runtime.CompilerServices.Unsafe",
286+
"System.Text.Encoding.CodePages",
287+
"System.Threading.Tasks.Extensions"
288+
};
289+
foreach (var assemblyFile in assemblies.Select(i => i + ".dll"))
290+
{
291+
var from = Path.Combine(Environment.CurrentDirectory, assemblyFile);
292+
var to = Path.Combine(Environment.CurrentDirectory, _installResourcesDir, AssemblyDir, assemblyFile);
293+
File.Copy(from, to, true);
294+
}
295+
}
253296
}
254-
}
297+
}

Source/Stationeers.Addons.Patcher/Stationeers.Addons.Patcher.csproj

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,16 +33,16 @@
3333
<WarningLevel>4</WarningLevel>
3434
</PropertyGroup>
3535
<ItemGroup>
36-
<Reference Include="Mono.Cecil, Version=0.11.3.0, Culture=neutral, PublicKeyToken=50cebf1cceb9d05e, processorArchitecture=MSIL">
36+
<Reference Include="Mono.Cecil, Version=0.11.4.0, Culture=neutral, PublicKeyToken=50cebf1cceb9d05e, processorArchitecture=MSIL">
3737
<HintPath>..\packages\Mono.Cecil.0.11.3\lib\net40\Mono.Cecil.dll</HintPath>
3838
</Reference>
39-
<Reference Include="Mono.Cecil.Mdb, Version=0.11.3.0, Culture=neutral, PublicKeyToken=50cebf1cceb9d05e, processorArchitecture=MSIL">
39+
<Reference Include="Mono.Cecil.Mdb, Version=0.11.4.0, Culture=neutral, PublicKeyToken=50cebf1cceb9d05e, processorArchitecture=MSIL">
4040
<HintPath>..\packages\Mono.Cecil.0.11.3\lib\net40\Mono.Cecil.Mdb.dll</HintPath>
4141
</Reference>
42-
<Reference Include="Mono.Cecil.Pdb, Version=0.11.3.0, Culture=neutral, PublicKeyToken=50cebf1cceb9d05e, processorArchitecture=MSIL">
42+
<Reference Include="Mono.Cecil.Pdb, Version=0.11.4.0, Culture=neutral, PublicKeyToken=50cebf1cceb9d05e, processorArchitecture=MSIL">
4343
<HintPath>..\packages\Mono.Cecil.0.11.3\lib\net40\Mono.Cecil.Pdb.dll</HintPath>
4444
</Reference>
45-
<Reference Include="Mono.Cecil.Rocks, Version=0.11.3.0, Culture=neutral, PublicKeyToken=50cebf1cceb9d05e, processorArchitecture=MSIL">
45+
<Reference Include="Mono.Cecil.Rocks, Version=0.11.4.0, Culture=neutral, PublicKeyToken=50cebf1cceb9d05e, processorArchitecture=MSIL">
4646
<HintPath>..\packages\Mono.Cecil.0.11.3\lib\net40\Mono.Cecil.Rocks.dll</HintPath>
4747
</Reference>
4848
<Reference Include="System" />
@@ -70,4 +70,4 @@
7070
<None Include="packages.config" />
7171
</ItemGroup>
7272
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
73-
</Project>
73+
</Project>

Source/Stationeers.VS.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
22
<PropertyGroup>
3-
<StationeersDirectory>X:\Path\To\Steam\steamapps\common\Stationeers\</StationeersDirectory> <!-- Change this to the path to your Stationeers directory -->
3+
<StationeersDirectory>/mnt/steam/lib_b/Steam/steamapps/common/Stationeers/</StationeersDirectory> <!-- Change this to the path to your Stationeers directory -->
44
</PropertyGroup>
55
</Project>

0 commit comments

Comments
 (0)